假设我有一个属性为:id, :first_name, :last_name, and :emailUser模型.在我的应用程序中,来宾用户不应该看到User's email and last_name.如果我想要一个用户列表,我知道如何 Select 特定的值,但我不知道如何获得特定用户的特定属性,比如

User.find_by(id: 5).select(:id, :first_name).

解决这个问题的一个办法是使用户

User.find_by(id: 5).attributes.slice('id', 'first_name') 

但我得到的是散列而不是AR记录.我能行

User.select(:id, :first_name).find_by(id: 1) 

但我不知道应该过滤哪些过滤器,因为我需要先了解用户.

你能帮我吗?

推荐答案

如果你想要一个数组而不是一个活动记录实例,那么Choco所说的就行了.如果需要活动记录实例,请执行以下操作:

User.where(id: 5).select(:id, :first_name).take 

这里有更多信息.我不确定你知道/不知道多少,所以我假设你知道的不是更多而是更少.

我假设你意识到你在上面做的是方法链接——也就是说,你在调用一个方法,然后根据第一个方法的结果调用另一个方法.例如:

User.find_by(id: 5).attributes.slice('id', 'first_name')

您正在调用User类上的find_by_id方法.该方法将返回User类中的instance(即活动记录实例).该实例有一个名为attributes的方法,您可以调用它.attributes方法返回Hash类的一个实例,代表前一个活动记录实例中的字段.Hash有一个slice方法,你依次调用它.slice方法返回Hash的另一个实例,其中包含指定字段的子集.

因此,需要明确的概念是,当你链接方法时,你并不是在同一件事上调用每个后续方法——你是在链中前一个方法的返回值上调用它.

好了,那么,既然这样:

所有find个方法都用于查询数据库并返回活动记录模型的单个实例,或者返回包含多个活动记录模型实例的普通rubyarray.

许多其他方法(selectwhere等)不会立即访问数据库,也不会返回活动记录实例.它们都返回ActiveRecord::Relation的一个实例.ActiveRecord::Relation有点像一组符合特定条件的潜在记录,你可以给它添加额外的条件.这就像"等待发生的数据库查询"或"可能发生或可能尚未发生的数据库查询".

当你在ActiveRecord::Relation上调用像whereorderselect这样的方法时,它将返回ActiveRecord::Relation的实例,这意味着你有一个相同类的实例,并且可以很好地从该类链接方法,例如:User.where(name: 'Fred').select(:id, :name).order('name ASC')

您的ActiveRecord::Relation实例将非常智能,在您调用一个明确表示您现在需要记录的方法之前,不会费心go 访问数据库,比如eachalltake等等.

所以,我走的路比计划的要长,所以我要结束了.以下是我第一次提到的代码,下面有一个详细的、有大量 comments 的解释:

User.where(id: 5).select(:id, :first_name).take

分解:

my_relation = User.where(id: 5)
# The database will not have been hit yet - my_relation 
# is a query waiting to happen

my_second_relation = my_relation.select(:id, :first_name)
# The database has STILL not been hit.
# the relation now contains both the conditions 
# from the previous my_relation, and the new 'select'
# criteria we specified

my_user = my_second_relation.take
# OK, 'take' means we want the first record
# matching all our criteria,
# so my_second_relation will hit the database 
# to get it, and then return an Active Record 
# instance (ie, an instance of the User class)

哇!我坚持的时间比预期的要长.希望其中一些有用!

Ruby-on-rails相关问答推荐

使用FactoryBot测试ActiveStorage的RSpec请求规范

是否可以使用 Turbo 帧更新 Rails 表单输入字段值?

`ActionController::API` 祖先类在加载后不会更新

rspec中日期时间结束时的分数是多少?

Rails 路由到唯一索引

Rails 100% 新手问题 - send() 方法

rails s和bundle exec rails s有什么区别?

File.open,写入和保存?

在一行中更改多个对象属性

如何更改 Heroku 应用程序的 DATABASE_URL

Rails 4,使用 ActiveRecord 的原始查询

为什么使用 HTTP PUT 和 DELETE 方法而不是 POST?

禁用 RVM 或使用没有 RVM 安装的 Ruby?

什么是 Ruby 中的 Python 文档字符串?

Ruby如何写入Tempfile

.increment vs += 1

Rails 引擎中的迁移?

ruby/ruby on rails 内存泄漏检测

按照给定 ID 数组的顺序按 ID 查找模型记录

Rails.cache 在测试之间被清除了吗?