Rails Scoping For has_many :through To Access Extr

2019-01-09 14:20发布

As we know, in rails you can add extra attributes to your has_many :through join model

I'd like to extract the extra data from the join model & populate the view with it. I have got this working by referencing the join model directly, but I'd like to append the relevant join-model data to the current item, like this:

#app/models/message.rb
    #Images
    has_many :image_messages, :class_name => 'ImageMessage'
    has_many :images, :class_name => 'Image', :through => :image_messages, dependent: :destroy

   #app/views/messages/show.html.erb
   <%= @message.image_messages.first.caption %> #-> works

   #app/views/messages/show.html.erb
   <%= @message.images.first.caption %> #-> what I'd like to happen

Specifically, I need to be able to call the caption of a particular image, with caption being stored in the image_messages join model, like this:

#image_messages join table
id | message_id | image_id | caption | created_at | updated_at

From what I've seen, might be able to use a scope for this, but I'm not sure

Any help will be appreciated! I figured I'd ask the question because it's one of those which you don't get that often!

1条回答
Viruses.
2楼-- · 2019-01-09 14:49

I actually found the solution to this

The magic lies in the SQL SELECT statement, which I managed to find out about on this RailsCast

Specifically, alongside the standard SELECT * FROM table, you can define another function, and attach it to the original query with the AS function

So what I got was this code:

#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

This allows you to attach the "caption" for the image to the Image object, allowing you to call @image.caption -- it works brilliantly!

查看更多
登录 后发表回答