Я думаю, что ваши модели выглядеть следующим образом:
class User < ActiveRecord::Base
has_many :reviews
end
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :reviewable, polymorphic: true
end
class Shop < ActiveRecord::Base
has_many :reviews, as: :reviewable
end
Вы не в состоянии сделать этот запрос по нескольким причинам.
- ActiveRecord не может создавать соединение без дополнительной информации.
- Там нет таблицы называется пересмотренным
Чтобы решить эту проблему, необходимо явно определить отношения между Review
и Shop
.
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :reviewable, polymorphic: true
# For Rails < 4
belongs_to :shop, foreign_key: 'reviewable_id', conditions: "reviews.reviewable_type = 'Shop'"
# For Rails >= 4
belongs_to :shop, -> { where(reviews: {reviewable_type: 'Shop'}) }, foreign_key: 'reviewable_id'
# Ensure review.shop returns nil unless review.reviewable_type == "Shop"
def shop
return unless reviewable_type == "Shop"
super
end
end
Тогда вы можете запросить так:
Review.includes(:shop).where(shops: {shop_type: 'cafe'})
Обратите внимание, что имя таблицы shops
и не reviewable
. Не должно быть таблицы, которую можно просмотреть в базе данных.
Я считаю, что это было проще и гибче, чем прямое определение join
между Review
и Shop
, поскольку оно позволяет загружать запросы в дополнение к запросам по связанным полям.
Причина, по которой это необходимо, заключается в том, что ActiveRecord не может создать соединение на основе только рассмотренных, поскольку несколько таблиц представляют другой конец соединения, а SQL, насколько мне известно, не позволяет вам присоединиться к таблице с именем по значению, хранящемуся в столбце. Определив дополнительную связь belongs_to :shop
, вы предоставляете ActiveRecord информацию, необходимую для завершения соединения.
Безупречный ответ и подробное объяснение. Благодарю. – Victor
На самом деле я закончил использование этого, не объявив ничего больше: '@reviews = @ user.reviews.joins (" INNER JOIN магазины ON (reviewable_type = 'Shop' AND shops.id = reviewable_id AND shops.shop_type = '"+ type + "')") включает (: user,: reviewable =>: photos) ' – Victor
Это работает? –