使用Rails 3.2,这段代码有什么问题?
@reviews = @ user.reviews.includes(:user, :reviewable) .where('reviewable_type =?AND reviewable.shop_type =?','Shop','cafe')它会引发此错误:
无法急切加载多态关联:reviewable
如果我删除了 reviewable.shop_type =?条件,它将起作用。
如何根据 reviewable_type 和 reviewable.shop_type (其中实际上是 shop.shop_type )?
解决方案我的猜测是模型如下:
class User< ActiveRecord :: Base has_many:reviews end class Review< ActiveRecord :: Base 属性_to:用户属性_to:可查看,多态:true end class Shop< ActiveRecord :: Base has_many:reviews,as::reviewable end由于多种原因,您无法执行该查询。
要解决此问题,您需要明确定义评论和 Shop 之间的关系。
类评论< ActiveRecord :: Base 属性_to:用户属性_to:可查看,多态:true #对于Rails< 4 nobody_to:shop,foreign_key: reviewable_id,条件: reviews.reviewable_type ='Shop' #对于Rails> = 4 属地属于:shop,-> {where(reviews:{reviewable_type:'Shop'})}},foreign_key:'reviewable_id'#确保review.shop返回nil,除非review.reviewable_type == Shop def shop 返回,除非reviewable_type == Shop 超级结束结束然后您可以这样查询:
Review.includes(:shop).where(shops:{shop_type:'cafe '})表名称为 shops ,而不是可查看。在数据库中不应有一个称为可复审的表。
我相信,这比显式定义 join 介于评论和商店之间,因为它除了让您查询相关字段外,还使您渴望加载。 / p>
之所以需要这样做,是因为ActiveRecord无法单独基于可审阅来建立联接,因为就我而言,多个表代表了联接的另一端,并且SQL知道,不允许您联接由存储在列中的值命名的表。通过定义额外的关系 belongs_to:shop ,您将为ActiveRecord提供完成连接所需的信息。
Using Rails 3.2, what's wrong with this code?
@reviews = @user.reviews.includes(:user, :reviewable) .where('reviewable_type = ? AND reviewable.shop_type = ?', 'Shop', 'cafe')It raises this error:
Can not eagerly load the polymorphic association :reviewable
If I remove the reviewable.shop_type = ? condition, it works.
How can I filter based on the reviewable_type and reviewable.shop_type (which is actually shop.shop_type)?
解决方案My guess is that your models look like this:
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 endYou are unable to do that query for several reasons.
To solve this issue, you need to explicitly define the relationship between Review and 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 endThen you can query like this:
Review.includes(:shop).where(shops: {shop_type: 'cafe'})Notice that the table name is shops and not reviewable. There should not be a table called reviewable in the database.
I believe this to be easier and more flexible than explicitly defining the join between Review and Shop since it allows you to eager load in addition to querying by related fields.
The reason that this is necessary is that ActiveRecord cannot build a join based on reviewable alone, since multiple tables represent the other end of the join, and SQL, as far as I know, does not allow you join a table named by the value stored in a column. By defining the extra relationship belongs_to :shop, you are giving ActiveRecord the information it needs to complete the join.
更多推荐
渴望负载多态
发布评论