Ruby on rails rails中关联作用域中左联接的子查询
我在ActiveRecord中使用Rails 4.2.0。我有Ruby on rails rails中关联作用域中左联接的子查询,ruby-on-rails,ruby-on-rails-4,activerecord,orm,left-join,Ruby On Rails,Ruby On Rails 4,Activerecord,Orm,Left Join,我在ActiveRecord中使用Rails 4.2.0。我有Case模型,它有很多注释 我的主要目标是在一个查询中获得每个案例的最新注释。注释字段应该是可排序的(按注释排序。例如,在创建),我可以通过这样的SQL查询实现这一点: SELECT cases.*, notes.* FROM cases LEFT OUTER JOIN notes ON cases.id = notes.case_id AND notes.id = ( SELECT id FROM notes WHERE
Case
模型,它有很多注释
我的主要目标是在一个查询中获得每个案例的最新注释。注释字段应该是可排序的(按注释排序。例如,在
创建),我可以通过这样的SQL查询实现这一点:
SELECT cases.*, notes.* FROM cases
LEFT OUTER JOIN notes ON cases.id = notes.case_id AND notes.id = (
SELECT id FROM notes
WHERE notes.case_id = cases.id
ORDER BY notes.created_at DESC
LIMIT 1
)
ORDER BY notes.created_at DESC
我当前的案例.rb
代码如下:
has_one :latest_note, -> do
where('id' => Note.where('"case_id" = "cases"."id"').order(created_at: :desc).limit(1))
end, inverse_of: :case, class_name: 'Note'
当使用eager\u load
时,它工作正常:Case.eager\u load(:latest\u note)。order('notes.created\u at DESC')
但是引发错误SQLite3::SQLException:没有这样的列:cases.id
没有eager\u load
:
Case.first.最新注释
SELECT "notes".* FROM "notes"
WHERE "notes"."case_id" = ? AND "notes"."id" IN (
SELECT "notes"."id" FROM "notes"
WHERE ("case_id" = "cases"."id")
ORDER BY "notes"."created_at" DESC
LIMIT 1
) LIMIT 1
还有没有没有没有关联作用域的解决方案?通过连接的原始左连接
不适用于eager\u load
。没有eager\u load
它不会将值从数据库映射到对象-日期保持为字符串,而不是DateTime
对象。我刚刚找到了解决方法:
根据我发现的范围,该范围可以接受所有者对象作为参数:
class User < ActiveRecord::Base
has_many :birthday_events, ->(user) { where starts_on: user.birthday }, class_name: 'Event'
end
但是,Rails 4.2.0
输出:
弃用警告:关联作用域“latest_note”依赖于实例(作用域块采用参数)。预加载发生在创建单个实例之前。这意味着没有实例被传递到关联作用域。这极有可能导致行为不正常或不正确。不推荐加入、预加载和快速加载这些关联,并将在将来删除
此外,此解决方法不适用于preload
(单独的SQL查询)通过使用连接而不是依赖于实例的where子句来避免警告:有许多:生日事件,->{joins(“事件上的连接事件.开始日期=用户.生日”},类名称:'Event'
class User < ActiveRecord::Base
has_many :birthday_events, ->(user) { where starts_on: user.birthday }, class_name: 'Event'
end
has_one :latest_note, ->(kase) do
subquery = Note.order(created_at: :desc).limit(1)
subquery = kase.is_a?(Case) ? subquery.where(case_id: kase.id) : subquery.where('"case_id" = "cases"."id"')
where('id' => subquery)
end, inverse_of: :case, class_name: 'Note'