Refactoring has_many with scopes

半世苍凉 提交于 2019-12-06 05:47:06

There's nothing inherently bad with conditions in your associations, specially if you need to eager load a subset of products.

However to achieve the scope you need, you must add it on the Product model and resort to plain sql since the filter is applied on a different model than the one it's defined on.

class Product
  # not tested 
  scope :wanted, ->{ where("ownerships.owning_dates IS NULL AND ...") }
end

IMHO you're better off with the first solution. The reason is, if for some reason you apply that scope inside a block of many users, you'll hit the O(n) wall despite eager loading the products.

User.includes(:owned_products).each do |user|
  user.onwned_products.wanted # => SQL connection
end

Update : just found out about merge an amazingly undocumented feature of ActiveRecord.

Among other uses, it allows you to do a join, and filter by a named scope on the joined model

In other words you can do :

user.owned_products.merge(Ownership.future)

Quit powerful !

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!