从ActiveRecord模型获取特定的属性 [英] Get specific attributes from an ActiveRecord model

查看:170
本文介绍了从ActiveRecord模型获取特定的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个属性:id,:first_name,:last_name和:email User >。在我的应用程序中,访客用户不应该看到用户的电子邮件和姓氏。我知道如何选择特定的值,如果我想要一个用户列表,但我不知道如何获得特定用户的特定属性,如$ / $>
$ b $

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

一个解决方案是给用户

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

但是我得到一个散列而不是AR记录。我可以这样做:
$ b $ pre $ User.select(:id,:first_name).find_by(id:1)

code>

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



你能帮我吗?

解决方案

数组不是活动的记录实例。如果你想要一个活动的记录实例,请执行以下操作:
$ b $ pre $ User.where(id:5).select(:id,:first_name )。

以下是更多信息。我不知道你有多少/不知道,所以我会假设你知道的更少,而不是更多。



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

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

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

所以,要清楚的概念是,当你链接方法时,你不会调用每个后续的方法在同一个东西上 - 你调用它的前一个返回值方法在链中。

OK,所以用那个方法:

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

很多其他方法 - select where 等等,不会碰到数据库马上,并不打算返回一个活跃的记录实例。它们都返回一个 ActiveRecord :: Relation 的实例。一个 ActiveRecord :: Relation 类似于一组符合特定条件的潜在记录,您可以添加额外的条件。这就像是一个'等待发生的数据库查询',或'可能发生或可能还没有发生过的数据库查询'。

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



ActiveRecord :: Relation 的实例将非常聪明,在调用方法之前不会打扰数据库这清楚地表明你现在需要记录 - 比如每个所有 code>等等。

因此,我在这里比计划中的时间要长,所以我会结束。这里是我第一次提到的代码,有一个细分,严重的评论解释如下:

  User.where(id:5)。选择(:id,:first_name)。使用

分解:

  my_relation = User.where(id:5)
#数据库不会被命中 - my_relation
#是查询等待发生

my_second_relation = my_relation.select(:id,:first_name)
#数据库仍然没有被击中。
#这个关系现在包含了前面my_relation中的条件
#和我们指定的新的'select'
#条件

my_user = my_second_relation.take
#OK,'take'意思是我们希望第一条记录
#符合我们所有的条件,
#这样my_second_relation将会碰到数据库
#来得到它,然后返回一个Active记录
#实例(即User类的一个实例)

哇...我比预期的时间还要长。希望它有一些有用的!

Let's say that I have a User model with attributes :id, :first_name, :last_name, and :email. In my application, guest users shouldn't see User's email and last_name. I know how to select specific values if I want a list of users but I don't know how I can get specific attributes of a specific user like

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

One solution to that is to user

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

but then I get a hash instead of an AR record. I could do

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

but the thing that I don't know which filters I should filter since I need to know the user first.

Could you help me?

解决方案

What Choco said will work if you want an array not an active record instance. If you want an active record instance, do:

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

Here's some more info. I'm not sure how much you do/don't know, so I'll assume you know less rather than more.

I assume you realise what you're doing above is method chaining - ie, you're calling a method, then calling another method on the result of the first method. For example:

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

You're calling the find_by_id method on the User class. That method will return an instance of the User class (ie, an active record instance). That instance has a method called attributes, which you call. The attributes method returns an instance of the Hash class, representing the fields in the previous active record instance. Hash has a slice method, which you call in turn. The slice method returns another instance of Hash, containing the subset of fields you specified.

So, the concept to be clear on is that when you're chaining methods, you're not calling each subsequent method on the same thing - you're calling it on the return value of the previous method in the chain.

OK, so with that out of the way:

All the find methods are intended to query the database and return a single instance of an Active Record model, or a plain ruby array containing multiple instances of Active Record models.

A lot of other methods - select, where, etc, do NOT hit the database right away, and are NOT intended to return an active record instance. They all return an instance of ActiveRecord::Relation. An ActiveRecord::Relation is kinda like a potential group of records matching certain conditions - and you can add extra conditions to it. It's like a 'database query waiting to happen', or a 'database query that may or may not have happened yet'.

When you call a method like where, order, or select on ActiveRecord::Relation, it will return an instance of ActiveRecord::Relation, meaning you've got an instance of the same class, and can chain methods from that class nicely eg: User.where(name: 'Fred').select(:id, :name).order('name ASC')

Your instance of ActiveRecord::Relation will be very smart, and won't bother hitting the database until you call a method that clearly indicates you want the records now - such as each, all, take, etc.

So, I've gone on way longer than planned here, so I'll wrap up. Here's the code I first mentioned, with a broken down, heavily commented explanation below:

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

breaking it down:

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)

Wow... I went on longer than expected. Hope some of it was useful!

这篇关于从ActiveRecord模型获取特定的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆