【问题标题】:Rails ActiveRecord joins with multiple tablesRails ActiveRecord 连接多个表
【发布时间】:2020-03-22 16:07:41
【问题描述】:

我有一个类别模型,它通过第三个模型 OfferCategory 属于商品模型。我对 PlumCake 模型也有类似的关联,它通过 PlumCakeCategory 模型与类别模型相关联。

类别:

has_many :offer_categories, dependent: :destroy, inverse_of: :category
has_many :offers, through: :offer_categories, source: :offer
has_many :plum_cake_categories, dependent: :destroy, inverse_of: :category
has_many :plum_cakes, through: :plum_cake_categories, source: :plum_cake

报价:

has_many :offer_categories, dependent: :destroy, inverse_of: :offer
has_many :categories, through: :offer_categories, source: :category, dependent: :destroy

报价类别:

belongs_to :offer
belongs_to :category

李子蛋糕:

 has_many :plum_cake_categories, dependent: :destroy, inverse_of: :plum_cake
has_many :categories, through: :plum_cake_categories, source: :category, dependent: :destroy

李子蛋糕类别:

belongs_to :plum_cake
belongs_to :category

以及类别/李子蛋糕的类似关联。

现在我想获取所选商品和李子蛋糕的所有类别。以下查询为我提供了 qualified_offer_ids 提供的类别列表。

Category.joins(:offer_categories).where(offer_categories: { offer_id: eligible_offer_ids })

我可以对 plum_cake 进行类似的查询,并获得这两个查询的唯一类别。

cat1 = Category.joins(:offer_categories).where(offer_categories: { offer_id: eligible_offer_ids })
cat2 = Category.joins(:plum_cake_categories).where(plum_cake_categories: { plum_cake_id: eligible_plum_cake_ids })
(cat1 + cat2).uniq

但是有没有办法在单个查询中得到相同的结果((cat1 + cat2).uniq)?

【问题讨论】:

  • Category.distinct.joins(:offer_categories, :plum_cake_categories).where(offer_categories: { offer_id: qualified_offer_ids }).where(plum_cake_categories: { plum_cake_id: qualified_plum_cake_ids })
  • @AniketShivamTiwari 上面查询的问题是在AND条件下一个一个执行。我想要 OR 值。
  • 您可以将缺少的模型添加到您的问题中吗?查看他们的关系。
  • @SebastianPalma 完成

标签: ruby-on-rails join activerecord rails-activerecord


【解决方案1】:

如果你不想改变你的结构:

Category.left_outer_joins(:offer_categories, :plum_cake_categories).where(offer_categories: { offer_id: eligible_offer_ids }).or(Category.left_outer_joins(:offer_categories, :plum_cake_categories).where(plum_cake_categories: { plum_cake_id: eligible_plum_cake_ids })).uniq

【讨论】:

  • left_outer_joins 似乎正在工作。请使用 left_outer_joins 更新您的答案。
【解决方案2】:

我认为如果您使用 rails STI(单表继承),您可以轻松实现您的功能。

如果您的结构如下所示:

class Category
  has_many :offer_categories, dependent: :destroy, inverse_of: :category
  has_many :offers, through: :offer_categories, source: :offer
  has_many :plum_cake_categories, dependent: :destroy, inverse_of: :category
  has_many :plum_cakes, through: :plum_cake_categories, source: :plum_cake
  has_many :sub_categories
end

class SubCategory
  belongs_to :offer
  belongs_to :plum_cake
  belongs_to :category
end

class OfferCategory < SubCategory
  validate_presence_of :offer_id
end

class PlumCakeCategory < SubCategory
  validate_presence_of :plum_cake_id
end

您的查询将是:

Category.joins(:sub_categories).where(sub_categories: { offer_id: eligible_offer_ids }).or(Category.joins(:sub_categories).where(sub_categories: { plum_cake_id: eligible_plum_cake_ids }))

STI documentation

【讨论】:

  • 我理解逻辑。但是在不修改数据库结构的情况下有什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-16
  • 2013-08-18
相关资源
最近更新 更多