情况如下:商店有很多产品,可以加入多个联盟。但店主可能不希望在某些联盟中展示某些产品。例如,销售电脑和手机的商店可能只想在“电话市场”中显示手机。
默认情况下,商店中的所有商品都会显示在一家商店加入的所有联盟中。所以我认为建立一个产品联盟黑名单(我知道这是一个坏名字......任何想法?)可能是一种方便的方式。
问题是:如何创建“has_many”以反映诸如函数shown_alliances
和shown_products
的行为之类的关系?
我需要这个,因为在其他地方需要Car.includes(:shop, :alliances)
,使用函数使其变得不可能。
产品:
class Product < ActiveRecord::Base
belongs_to :store
has_many :alliances, -> { uniq }, through: :store
has_many :blacklists
def shown_alliances
alliances.where.not(id: blacklists.pluck(:alliance_id))
end
end
商店:
class Store < ActiveRecord::Base
has_many :products
has_many :alliance_store_relationships
has_many :alliances, through: :alliance_store_relationships
has_many :allied_products, -> { uniq }, through: :alliances, source: :products
end
联盟:
class Alliance < ActiveRecord::Base
has_many :alliance_store_relationships
has_many :store, through: :alliance_store_relationships
has_many :products, -> { uniq }, through: :companies
has_many :blacklists
def shown_produtcts
@produtcts ||= produtcts.where.not(id: blacklists.pluck(:produtct_id))
end
end
黑名单:
class Blacklist < ActiveRecord::Base
belongs_to :produtct
belongs_to :alliance
validates :produtct_id, presence: true,
uniqueness: { scope: :alliance_id }
end
答案 0 :(得分:1)
class Product < ActiveRecord::Base
# ...
has_many :shown_alliances, ->(product) { where.not(id: product.blacklists.pluck(:alliance_id) }, class_name: 'Alliance', through: :store, source: :alliances
# ...
end
class Alliance < ActiveRecord::Base
# ...
has_many :shown_products, ->(alliance) { where.not(id: alliance.blacklists.pluck(:product_id) }, class_name: 'Product', through: :companies, source: :products
# ...
end
您可以为关联指定条件。见docs here