Vic*_*tor 98 activerecord ruby-on-rails ruby-on-rails-3
使用Rails 3.2,这段代码出了什么问题?
@reviews = @user.reviews.includes(:user, :reviewable)
.where('reviewable_type = ? AND reviewable.shop_type = ?', 'Shop', 'cafe')
Run Code Online (Sandbox Code Playgroud)
它引发了这个错误:
无法急切加载多态关联:可审核
如果我删除reviewable.shop_type = ?
条件,它的工作原理.
如何基于reviewable_type
和reviewable.shop_type
(实际上shop.shop_type
)进行过滤?
Sea*_*ill 195
我的猜测是你的模型看起来像这样:
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
Run Code Online (Sandbox Code Playgroud)
由于多种原因,您无法执行该查询.
为了解决这个问题,你需要明确定义之间的关系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
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样查询:
Review.includes(:shop).where(shops: {shop_type: 'cafe'})
Run Code Online (Sandbox Code Playgroud)
请注意,表名是shops
不reviewable
.数据库中不应该有一个名为reviewable的表.
我相信这比明确定义join
之间更容易和更灵活Review
,Shop
因为除了通过相关字段查询之外,它还允许您急切加载.
这是必要的原因是ActiveRecord不能单独基于可审阅的构建连接,因为多个表代表连接的另一端,并且据我所知,SQL不允许您加入由存储的值命名的表在一列中.通过定义额外关系belongs_to :shop
,您将为ActiveRecord提供完成连接所需的信息.
小智 8
没有足够的声誉来发表评论来扩展上述 Moses Lucas 的响应,我必须进行一些小调整才能使其在 Rails 7 中工作,因为我收到以下错误:
ArgumentError: Unknown key: :foreign_type. Valid keys are: :class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading, :autosave, :required, :touch, :polymorphic, :counter_cache, :optional, :default
Run Code Online (Sandbox Code Playgroud)
代替 belongs_to :shop, foreign_type: 'Shop', foreign_key: 'reviewable_id'
我和 belongs_to :shop, class_name: 'Shop', foreign_key: 'reviewable_id'
这里唯一的区别是更改foreign_type:
为class_name:
!
小智 7
如果您收到ActiveRecord :: EagerLoadPolymorphicError,这是因为当仅支持多态关联时includes
决定调用。在此处的文档中:http : //api.rubyonrails.org/v5.1/classes/ActiveRecord/EagerLoadPolymorphicError.htmleager_load
preload
因此,始终preload
用于多态关联。需要注意的是:您不能在where子句中查询多态关联(这很有意义,因为多态关联表示多个表。)
归档时间: |
|
查看次数: |
38831 次 |
最近记录: |