在 Rails 中使用带有 has_many 的委托? [英] Using Delegate With has_many In Rails?

查看:26
本文介绍了在 Rails 中使用带有 has_many 的委托?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有 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

<小时>

额外属性

我们希望从连接模型 (ImageMes​​sage) 中提取额外的属性,并在 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_onebelongs_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 模型从 ImageMes​​sage 连接模型返回 .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.

我查看并发现在这种情况下没有必要进行任何关联.ImageMes​​sage的类方法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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆