Ответ 1
Я предполагаю, что ваши модели выглядят так:
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 информацию, необходимую для завершения соединения.