从ActiveRecord模型中获取特定属性

时间:2014-11-20 10:36:26

标签: ruby-on-rails select filter authorization

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

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) 

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

你能帮帮我吗?

4 个答案:

答案 0 :(得分:83)

如果你想让一个数组不是一个活动的记录实例,Choco说会有什么用。如果需要活动记录实例,请执行以下操作:

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

这里有更多信息。我不知道你做了多少/不知道多少,所以我假设你知道的更少而不是更多。

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

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

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

所以,要明确的概念是,当你链接方法时,你并没有在同一个东西上调用每个后续方法 - 你在它的返回值上调用它。链中的先前方法。

好的,这样就可以了:

所有find方法都用于查询数据库并返回Active Record模型的单个实例,或者包含多个Active Record模型实例的普通ruby数组。

许多其他方法 - selectwhere等不会立即命中数据库,也不会返回活动记录实例。它们都返回ActiveRecord::Relation的实例。 ActiveRecord::Relation有点像符合某些条件的潜在记录组 - 您可以为其添加额外条件。它就像一个等待发生的数据库查询,或者一个可能已经发生过或者可能没有发生过的数据库查询。

当您在where上调用类似orderselectActiveRecord::Relation的方法时,它会返回ActiveRecord::Relation的实例,这意味着您&#39 ;有一个同一个类的实例,可以很好地链接该类的方法,例如:User.where(name: 'Fred').select(:id, :name).order('name ASC')

ActiveRecord::Relation的实例非常聪明,在您调用一个明确表示您现在需要记录的方法之前,不会打扰数据库,例如each,{{ 1}},all

所以,我已经比这里计划的时间更长,所以我将结束。这是我第一次提到的代码,下面有一个细分的,大量评论的解释:

take

打破它:

User.where(id: 5).select(:id, :first_name).take
哇...我比预期的还要长。希望其中一些有用!

答案 1 :(得分:23)

试试这个:

User.where(id: 5).pluck(:id, :first_name) 

它返回包含id和first_name值的数组

答案 2 :(得分:4)

这也适用

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

答案 3 :(得分:0)

具有这样的要求,但需要更通用的东西,即只从模型中收集方法名称和值的列表(包括属性)。因此,我将此方法添加到了模型中:

  def attributes_from_keys(*keys)
    keys.inject({}) do |hash_to_return, key|
      hash_to_return.merge(key => send(key))
    end
  end

然后,使用以下方法调用此方法:

MyModel.find(1).attributes_from_keys(:id, :name, :age)

返回

{id: 1, name: 'Lawrence', age: 23}