はじめに
本記事はRails5.2にて作成されています、他のバージョンでの互換性を保証しません。
Table構成
Model構成
#### item.rb ####
class Item < ActiveRecord::Base
belongs_to :order
end
#### order.rb ####
class Order < ActiveRecord::Base
has_many :items
has_many :reviews
end
#### review.rb ####
class Review < ActiveRecord::Base
belongs_to :order
has_many :themes
end
#### theme.rb ####
class Theme < ActiveRecord::Base
belongs_to :review
end
各種実装
多段Association
orderからthemeを二段has_many
したい & themeからorderを二段belongs_to
したい
#### order.rb ####
class Order < ActiveRecord::Base
# ...
has_many :themes, through: :reviews
end
#### theme.rb ####
class Theme < ActiveRecord::Base
# ...
delegate :order, to: :reviews
end
注意: has_many, through
の逆はdelegate, to
を使います
こんなSQLが発行されます:
pry(main)> Theme.last.order
Theme Load (0.4ms) SELECT `reviews`.* FROM `reviews` ORDER BY `reviews`.`id` DESC LIMIT 1
Review Load (0.3ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`id` = 1 LIMIT 1
Order Load (0.5ms) SELECT `orders`.* FROM `orders` INNER JOIN `reviews` ON `reviews`.`id` = `orders`.`review_id` WHERE `orders`.`review_id` = 1 LIMIT 1
多段Scope(多段Joins)
item
をreview.text
でsortしたい
#### item.rb ####
class Item < ActiveRecord::Base
# ...
scope :join_reviews, -> { joins(:order, order: :reviews) }
end
こんなSQLが発行されます:
pry(main)> Item.all.order("review.theme_id desc")
Item Load (7.0ms) SELECT `items`.* FROM `items` INNER JOIN `orders` ON `orders`.`id` = `items`.`order_id` INNER JOIN `reviews` ON `reviews`.`order_id` = `orders`.`id` ORDER BY reviews.text DESC
delegate
危険説(2019-09-15更新)
こちらの記事が書いたように、delegate
文を使うと、Ransackが不発になっちゃう事象は、筆者も確認できましたので。多段belongs_to
を組む時、この記事が書いたように、has_one through
が有効であることもわかりました。
参考
https://blog.toshimaru.net/belongs_to-through/
https://qiita.com/takashisite/items/9d1484b88708e2872134
https://qiita.com/ishidamakot/items/7dba557d764362a828ff
https://qiita.com/rorensu2236/items/6a97e829f4e5940e8d7e
https://blog.toshimaru.net/belongs_to-through/