ActiveRecord::Relation 上的 Rails + 查询/范围不起作用

Rails + Query / Scope on ActiveRecord::Relation Not Working

提问人:RahulOnRails 提问时间:10/4/2023 最后编辑:mechnicovRahulOnRails 更新时间:10/4/2023 访问量:36

问:

在 Rails 控制台上,尝试查找一些数据。 型号: User

class User < ApplicationRecord    
  scope :active,    -> { where(status: true) }
  scope :inactive,  -> { where(status: false) }    
end

Rails 控制台

users = User.all
User Load (0.8ms)  SELECT  `users`.* FROM `users` LIMIT 11

输出 - 用户对象

#<ActiveRecord::Relation [#<User id: 1, name: "John", status: true >,#<User id: 2, name: "Micheal", status: false >,#<User id: 3, name: "Denis", status: true >,#<User id: 4, name: "Arnold", status: true> ...]>

现在尝试从上述对象中查找活动用户。

active_users = users.active
User Load (0.2ms)  SELECT  `users`.* FROM `users` WHERE `users`.`status` = TRUE LIMIT 11

输出 - 处于活动状态的用户

#<ActiveRecord::Relation [#<User id: 1, name: "John", status: true >,#<User id: 3, name: "Denis", status: true >,#<User id: 4, name: "Arnold", status: true > ...]>

在这里,尝试从 ActiveRecord 对象中查找活动用户,但不知何故,SQL 查询在数据库上运行,而不是过滤对象中的记录。

这是过滤对象的正确方法还是任何其他方法?

Ruby-on-Rails Ruby-on-Rails-5 Rails-ActiveRecord

评论

1赞 max 10/4/2023
将名为“status”的列设置为布尔值绝对不是正确的方法。
0赞 mechnicov 10/4/2023
@max好人。哈哈,写答案时我什至没有注意到
0赞 RahulOnRails 10/5/2023
@max - 请建议列名 - 例如 - 使用户处于活动/非活动状态 - 作为布尔类型的列名,对吗?active
1赞 max 10/5/2023
active作为布尔值会更有意义。但你也可以使用枚举而不是布尔值。railstips.org/blog/archives/2012/10/10/......

答:

0赞 mechnicov 10/4/2023 #1

看起来这里有两个误解:关于关系和关于范围

Active Record 关系对象是某种基于 SQL 查询的 Ruby 包装器。并且只有在关系上调用某些方法时才会执行它。例如,或 ,或其他一些。当您只是链接关系方法时,它不会调用对数据库的请求。这是关系的简化概念eachfirst

例如,你有这样的方法

def active_users
  users = User.all
  active_users = users.active
end

并将其称为 ,在这种情况下,它只是一个查询puts active_usersSELECT * FROM users WHERE active = TRUE

如果您尝试在 rails 控制台中逐行执行方法主体,它将是两个查询 ( 和 )。这是因为在控制台方法的后台被调用SELECT * FROM usersSELECT * FROM users WHERE active = TRUEinspect

在 rails 中,使用这种链接是很常见的模式

users = User.all
users = users.active if only_active_needs?
users = users.recent_registerd if only_recent_registered_needs?
puts users

在此示例中,将只执行一个查询(仅在最后一行)。再次请注意,在控制台中逐行执行可能会调用三个查询

scope 添加类方法。基本上它应该返回关系。正如你所猜到的,示波器的一个特点是链接/组合

因此,您尝试筛选记录看起来不错。有时会执行第二个查询。还行