在 Rails 中使用带有 has_many 的委托? [英] Using Delegate With has_many In Rails?
问题描述
我们有 2 个模型和一个连接模型:
We've got 2 models & a join model:
#app/models/message.rb
Class Message < ActiveRecord::Base
has_many :image_messages
has_many :images, through: :image_messages
end
#app/models/image.rb
Class Image < ActiveRecord::Base
has_many :image_messages
has_many :messages, through: :image_messages
end
#app/models/image_message.rb
Class ImageMessage < ActiveRecord::Base
belongs_to :image
belongs_to :message
end
<小时>
额外属性
我们希望从连接模型 (ImageMessage
) 中提取额外的属性,并在 Message
模型中访问它们:
We're looking to extract the extra attributes from the join model (ImageMessage
) and have them accessible in the Message
model:
@message.image_messages.first.caption # -> what happens now
@message.images.first.caption #-> we want
我们已经在声明关联时使用 select
方法实现了这一点:
We've already achieved this using the select
method when declaring the association:
#app/models/message.rb
has_many :images, -> { select("#{Image.table_name}.*", "#{ImageMessage.table_name}.caption AS caption") }, class_name: 'Image', through: :image_messages, dependent: :destroy
<小时>
委托
我们刚刚找到了 delegate
方法,它可以正是这需要的.但是,它似乎只适用于 has_one
和 belongs_to
关联
We've just found the delegate
method, which does exactly what this needs. However, it only seems to work for has_one
and belongs_to
associations
我们只是使用单个关联来实现它,但它似乎不适用于集合(只是将您带到公共方法)
We just got this working with a single association, but it seems it does not work for collections (just takes you to a public method)
问题
你知道有什么方法可以通过 Image
模型从 ImageMessage
连接模型返回 .caption
属性吗?
Do you know any way we could return the .caption
attribute from the ImageMessage
join model through the Image
model?
我们目前有这个:
#app/models/image.rb
Class Message < ActiveRecord::Base
has_many :image_messages
has_many :messages, through: :image_messages
delegate :caption, to: :image_messages, allow_nil: true
end
#app/models/image_message.rb
Class ImageMessage < ActiveRecord::Base
belongs_to :image
belongs_to :message
def self.caption # -> only works with class method
#what do we put here?
end
end
<小时>
更新
感谢 Billy Chan(对于实例方法的想法),我们已经让它非常运行起来:
Thanks to Billy Chan (for the instance method idea), we have got it working very tentatively:
#app/models/image.rb
Class Image < ActiveRecord::Base
#Caption
def caption
self.image_messages.to_a
end
end
#app/views/messages/show.html.erb
<%= @message.images.each_with_index do |i, index| %>
<%= i.caption[index][:caption] %> #-> works, but super sketchy
<% end %>
任何重构方法,特别是获取它以便每次调用 .caption
时,它都会返回该特定记录的 image_message.caption
值?
Any way to refactor, specifically to get it so that each time .caption
is called, it returns the image_message.caption
value for that particular record?
推荐答案
delegate
只是等效实例方法的简写.这不是所有人的解决方案,甚至还有一些争论说它不是那么明确.
delegate
is just a shorthand as equivalent instance method. It's not a solution for all, and there are even some debate that it's not so explicit.
当简单的delegate
不能适应时,您可以使用实例方法.
You can use an instance method when simple delegate
can't fit.
我查看并发现在这种情况下没有必要进行任何关联.ImageMessage的类方法caption更像是一个常量,可以直接引用.
I reviewed and found any association is unnecessary is this case. The ImageMessage's class method caption is more like a constant, you can refer it directly.
def image_message_caption
ImageMessage.caption
end
这篇关于在 Rails 中使用带有 has_many 的委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!