我有Subscription
和Article
之间的has_many
关系,文章有Product
。如何使用活动记录方法获取相关收藏(代理收藏)
class Subscription < ActiveRecord::Base
has_many :articles
end
class Article < ActiveRecord::Base
belongs_to :subscription
belongs_to :product
end
class Product < ActiveRecord::Base
has_many :subscriptions
end
现在。我想简单地从我的订阅中提取所有产品。
解决方案includes
:
class Subscription < ActiveRecord::Base
has_many :articles
def products
articles.includes(:product).map{|a| ap.product} # Or .map(&:product)
end
end
解决方案has_many :through
:
class Subscription < ActiveRecord::Base
has_many :articles
has_many :products, through: articles
end
首先有它不返回,可以在(例如subscription.products.pluck(:id)
)被链接的集合的缺点,而是一个简单的阵列。
第二个不完全是'语义上'正确的:我不希望它成为一个全面的关联,而只是帮助获取列表。
我是否简单地忽略了一些activerecord方法,它允许我获取相关联的项目?
你能澄清为什么你不希望这是“has_many通过”?从外部看来这是理想的解决方案。 – rossta 2014-10-11 15:24:35
'bar has_many:foo,through::baz'不仅仅是让我获取'self.baz.foo':它为我的公共接口添加了很多方法和东西。而且,它向外界传达了自我,foo和酒吧之间的联系。更糟糕的是,这是一个抽象的抽象:突然我的酒吧知道'baz'和'foo'是如何耦合的。而在干净的面向对象中,我根本就不会对它感兴趣:只是因为我把'foo'发送给了我的'baz';而已。 – berkes 2014-10-14 19:29:35
啊,是的,这都是事实。引用乔尔的话说,“所有不平凡的抽象在某种程度上都是漏洞”。 ActiveRecord既方便又妥协。一般来说,我们可以花时间与框架的约定作斗争,并且更加努力地在所提供的内容之外强制执行其他约定,或者我们可以轻松做到这一点。在某些情况下,我发现许多这些担忧并不重要,但这就是所有的角度。 – rossta 2014-10-15 05:40:56