Meu palpite é que seus modelos são assim:
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
Você não pode fazer essa consulta por vários motivos.
- ActiveRecord não é capaz de construir a junção sem informações adicionais.
- Não há nenhuma tabela chamada revisável
Para resolver esse problema, você precisa definir explicitamente a relação entre Review
e 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
Então você pode consultar assim:
Review.includes(:shop).where(shops: {shop_type: 'cafe'})
Observe que o nome da tabela é shops
e não reviewable
. Não deve haver uma tabela chamada revisável no banco de dados.
Acredito que isso seja mais fácil e flexível do que definir explicitamente o join
entre Review
e, Shop
pois permite que você carregue com antecedência, além de consultar por campos relacionados.
A razão pela qual isso é necessário é que ActiveRecord não pode construir uma junção baseada apenas em revisável, uma vez que várias tabelas representam a outra extremidade da junção, e o SQL, até onde eu sei, não permite que você junte uma tabela nomeada pelo valor armazenado em uma coluna. Ao definir o relacionamento extra belongs_to :shop
, você está fornecendo ao ActiveRecord as informações de que precisa para concluir a associação.
@reviews = @user.reviews.joins("INNER JOIN shops ON (reviewable_type = 'Shop' AND shops.id = reviewable_id AND shops.shop_type = '" + type + "')").includes(:user, :reviewable => :photos)