Rails (4.0.0) can do this - we have two ways to do it currently:
1. SQL "Alias" Columns
Rails Scoping For has_many :through To Access Extra Data
#Images
has_many :image_messages, :class_name => 'ImageMessage'
has_many :images, -> { select("#{Image.table_name}.*, #{ImageMessage.table_name}.caption AS caption") }, :class_name => 'Image', :through => :image_messages, dependent: :destroy
2. ActiveRecord Association Extensions
This is a little-known feature of Rails, which allows you to play with the collection
object. The way it does it is to extend the has_many
relationship you have created:
class AccountGroup < ActiveRecord::Base
has_many :accounts do
def X
#your code here
end
end
end
We have only got this method working for collections, but you can do all sorts with it. You should look at this tutorial to see more about it
Update
We just got this working by using an extension module:
#app/models/message.rb
Class Message < ActiveRecord::Base
has_many :image_messages #-> join model
has_many :images, through: :image_messages, extend: ImageCaption
end
#app/models/concerns/image_caption.rb
module ImageCaption
#Load
def load
captions.each do |caption|
proxy_association.target << caption
end
end
#Private
private
#Captions
def captions
return_array = []
through_collection.each_with_index do |through,i|
associate = through.send(reflection_name)
associate.assign_attributes({caption: items[i]})
return_array.concat Array.new(1).fill( associate )
end
return return_array
end
#######################
# Variables #
#######################
#Association
def reflection_name
proxy_association.source_reflection.name
end
#Foreign Key
def through_source_key
proxy_association.reflection.source_reflection.foreign_key
end
#Primary Key
def through_primary_key
proxy_association.reflection.through_reflection.active_record_primary_key
end
#Through Name
def through_name
proxy_association.reflection.through_reflection.name
end
#Through
def through_collection
proxy_association.owner.send through_name
end
#Captions
def items
through_collection.map(&:caption)
end
#Target
def target_collection
#load_target
proxy_association.target
end
end
Props to this gist for the variable functions
This basically overrides the load
ActiveRecord function in the CollectionProxy
class, and uses it to create our own proxy_association.target
array :)
If you need any information on how to implement, just ask in the comments