如何将此SQL查询转换为Rails Active Record?

时间:2018-09-11 00:56:28

标签: ruby-on-rails ruby rails-activerecord

我有以下查询:

SELECT * FROM users 
JOIN locations 
ON locations.id = (
    SELECT id from locations 
    WHERE locations.user_id = users.id 
    ORDER BY locations.created_at 
    desc LIMIT 1
)

这基本上意味着我有2个模型(用户,位置),其中用户具有多个位置。

我期望的结果是:对于每个用户,我想拉出他们的最后一个位置。

如何仅使用ActiveRecord做到这一点?

3 个答案:

答案 0 :(得分:3)

您可以创建has_one关联

class User
  has_one :last_location, -> { order 'created_at DESC' }, class_name: "Location"
end

那你就可以做

users = User.includes(:last_location)
users.each { |u| u.last_location; ... }

答案 1 :(得分:1)

我认为最简单的方法是在Location模型上添加一个范围以返回最新位置。

虽然这与您手动编写的SQL不同,但它应该提供相同的结果。

location.rb

scope :most_recent, -> { order(created_at: :desc).limit(1) }

然后类似:

user = User.last
user.locations.most_recent

这应该为您提供此SQL输出,它将为用户返回最近创建的位置。

SELECT  "locations".* FROM "locations" WHERE "locations"."user_id" = $1  ORDER BY "locations"."created_at" DESC LIMIT 1

答案 2 :(得分:0)

您可以尝试以下方法:

 User.where("id in (SELECT user_id from locations l 
        INNER JOIN users u ON u.id = l.user_id ORDER BY l.created_at desc LIMIT 1)")