在 rails 中加入 has_many_through
Join for has_many_through in rails
我有以下3个型号。
class Order
belongs_to :item
belongs_to :category
end
class Item
has_many :orders
belongs_to :category
end
class Category
has_many :items
has_many :orders, through: :items
end
我想像 Order.joins(:item).joins(:category)
一样加入表格,但它不起作用。
期望 SQL 是
SELECT * FROM `orders`
INNER JOIN `items` ON `items`.`id` = `orders`.`item_id`
INNER JOIN `categories` ON `items`.`category_id` = `categories`.`id`
希望对你有所帮助。
您要找的语法是
Order.joins(item: :category)
查看 here 了解更多信息。
我有点困惑,因为 Order 和 Item 都 belongs_to Category 和 Category 已经 has_many 使用该设置的订单,:through
选项是不必要的。
对于您想要的输出,我猜您想进行嵌套连接(订单 > 商品 > 类别)而不是多重连接(订单 > 商品+类别)
https://guides.rubyonrails.org/active_record_querying.html#joining-multiple-associations
12.1.3.1 Joining Nested Associations (Single Level)
Article.joins(comments: :guest)
This produces:
SELECT articles.* FROM articles
INNER JOIN comments ON comments.article_id = articles.id
INNER JOIN guests ON guests.comment_id = comments.id
所以,你应该做类似 Order.joins(item: :category)
的事情
设置这些关联的正确方法是:
class Order < ApplicationRecord
belongs_to :item
# This references items.category_id
has_one :category, through: :item
end
class Item < ApplicationRecord
has_many :orders
belongs_to :category
end
class Category < ApplicationRecord
has_many :item, through: :orders
has_many :orders
end
您想删除 orders.category_id
列(如果它存在)并通过项目 table 使用间接关联以避免重复。 belongs_to
和 has_one
的语义可能令人困惑,但 belongs_to
假设外键在 这个模型 (订单)上,而 has_one
将它放在 其他模型 table(项目)上。
这将使您 join/include/eager_load 与以下对象建立联系:
irb(main):002:0> Order.joins(:category)
Order Load (1.4ms) SELECT "orders".* FROM "orders" INNER JOIN "items" ON "items"."id" = "orders"."item_id" INNER JOIN "categories" ON "categories"."id" = "items"."category_id" LIMIT [["LIMIT", 11]]
如您所见,Rails 将自动处理加入table(项目)。
如果您希望加载两个关联,您可以使用散列或只列出两者:
Order.eager_load(item: :category)
Order.eager_load(:item, :category)
我有以下3个型号。
class Order
belongs_to :item
belongs_to :category
end
class Item
has_many :orders
belongs_to :category
end
class Category
has_many :items
has_many :orders, through: :items
end
我想像 Order.joins(:item).joins(:category)
一样加入表格,但它不起作用。
期望 SQL 是
SELECT * FROM `orders`
INNER JOIN `items` ON `items`.`id` = `orders`.`item_id`
INNER JOIN `categories` ON `items`.`category_id` = `categories`.`id`
希望对你有所帮助。
您要找的语法是
Order.joins(item: :category)
查看 here 了解更多信息。
我有点困惑,因为 Order 和 Item 都 belongs_to Category 和 Category 已经 has_many 使用该设置的订单,:through
选项是不必要的。
对于您想要的输出,我猜您想进行嵌套连接(订单 > 商品 > 类别)而不是多重连接(订单 > 商品+类别)
https://guides.rubyonrails.org/active_record_querying.html#joining-multiple-associations
12.1.3.1 Joining Nested Associations (Single Level) Article.joins(comments: :guest)
This produces:
SELECT articles.* FROM articles INNER JOIN comments ON comments.article_id = articles.id INNER JOIN guests ON guests.comment_id = comments.id
所以,你应该做类似 Order.joins(item: :category)
设置这些关联的正确方法是:
class Order < ApplicationRecord
belongs_to :item
# This references items.category_id
has_one :category, through: :item
end
class Item < ApplicationRecord
has_many :orders
belongs_to :category
end
class Category < ApplicationRecord
has_many :item, through: :orders
has_many :orders
end
您想删除 orders.category_id
列(如果它存在)并通过项目 table 使用间接关联以避免重复。 belongs_to
和 has_one
的语义可能令人困惑,但 belongs_to
假设外键在 这个模型 (订单)上,而 has_one
将它放在 其他模型 table(项目)上。
这将使您 join/include/eager_load 与以下对象建立联系:
irb(main):002:0> Order.joins(:category)
Order Load (1.4ms) SELECT "orders".* FROM "orders" INNER JOIN "items" ON "items"."id" = "orders"."item_id" INNER JOIN "categories" ON "categories"."id" = "items"."category_id" LIMIT [["LIMIT", 11]]
如您所见,Rails 将自动处理加入table(项目)。
如果您希望加载两个关联,您可以使用散列或只列出两者:
Order.eager_load(item: :category)
Order.eager_load(:item, :category)