Rails ActiveRecord 连接多个表
Rails ActiveRecord joins with multiple tables
我有一个类别模型,它通过第三个模型 OfferCategory 属于 Offer 模型。我也有一个类似的 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
以及 category/plumcakes 的类似关联。
现在我想获取所选优惠和李子蛋糕的所有类别。以下查询为我提供了 eligible_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)?
我认为如果您使用 rails STI(单一 table 继承),您可以轻松实现您的功能。
如果您的结构如下所示:
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 }))
如果您不想更改结构:
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
我有一个类别模型,它通过第三个模型 OfferCategory 属于 Offer 模型。我也有一个类似的 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
以及 category/plumcakes 的类似关联。
现在我想获取所选优惠和李子蛋糕的所有类别。以下查询为我提供了 eligible_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)?
我认为如果您使用 rails STI(单一 table 继承),您可以轻松实现您的功能。
如果您的结构如下所示:
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 }))
如果您不想更改结构:
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