如何使用“includes”和“where”条件

时间:2016-06-08 13:46:05

标签: ruby-on-rails ruby activerecord

情况如下:商店有很多产品,可以加入多个联盟。但店主可能不希望在某些联盟中展示某些产品。例如,销售电脑和手机的商店可能只想在“电话市场”中显示手机。

默认情况下,商店中的所有商品都会显示在一家商店加入的所有联盟中。所以我认为建立一个产品联盟黑名单(我知道这是一个坏名字......任何想法?)可能是一种方便的方式。

问题是:如何创建“has_many”以反映诸如函数shown_alliancesshown_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

1 个答案:

答案 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