使用Rails查询返回单个字段

yel*_*ign 5 mysql hash activerecord ruby-on-rails

我遇到的问题应该很容易,但我不知道我做错了什么.我只是尝试执行一个返回单个字段的查询,而不是Rails 3中的完整记录.

模型方法

def self.find_user_username(user_id)
  user_name = User.select("user_name").where(user_id)
  return user_name
end
Run Code Online (Sandbox Code Playgroud)

我正盯着Rails指南(http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields),它简单地说(其中viewable_by,locked = fields):

Client.select("viewable_by, locked")
Run Code Online (Sandbox Code Playgroud)

我试过翻转选择,就像这样:

User.select("user_name").where(user_id) - AND - 
User.where(user_id).select("user_name")
Run Code Online (Sandbox Code Playgroud)

但都没有工作.事实上,我甚至尝试过:

user_name = User.select("yoda").where(user_id)
Run Code Online (Sandbox Code Playgroud)

我没有得到错误.当我查看视图时,我在哪里:

Friend.find_user_username(friend.user_id)
Run Code Online (Sandbox Code Playgroud)

我只是不断得到哈希:ActiveRecord :: Relation:0x2f4942f0

Ald*_*uca 22

User.where(:id => user_id).pluck(:user_name).first
Run Code Online (Sandbox Code Playgroud)

应该做你想做的事.

pluck "接受列名作为参数,并返回指定列的值数组以及相应的数据类型"

  • 我会在`where`之后为这个查询添加一个`.limit(1)`,否则你将把数据库中的所有结果都拉到内存中. (7认同)
  • @OskarHolmkratz在上面的代码中,`.first`_does not_执行`limit(1)`,因为它不是被调用的`ActiveRelation#first`方法,而是调用`Array#first`.`ActiveRelation#pluck`返回一个数组(不是另一个`ActiveRelation`对象).如果你正在调用`ActiveRelation#first`,那么是的,它会执行`limit(1)`.如果你真的想在上面的例子中,你需要`User.where(:id => user_id).limit(1).pluck(:user_name).first`. (4认同)
  • `pluck`是在Rails 3.2中引入的. (2认同)
  • 不需要限制1,因为id字段查询实际上返回多个记录的可能性非常小. (2认同)

Jan*_*sch 9

Rails 6 推出ActiveRecord::Relation#pick

pick(:foo)相当于limit(1).pluck(:foo).first.


Ald*_*uca -3

顺便说一句,如果问题是关于 ActiveRecord::Relation 的,那么它是由 where 和 select 返回的对象的类,正如您正在阅读的 Rails 指南中所述。它经过优化,可在多个方法之间链接,并且当您实际访问关联的元素时,您将获得模型对象(因此在幕后,SQL 查询仅运行一次)。这意味着您获得了 Relation 对象,因为您只需返回它。

在这种情况下,也许最好的解决方案就是使用 find 并访问 user_name 属性

def self.find_user_username(user_id)
  User.find(user_id).user_name
end
Run Code Online (Sandbox Code Playgroud)

该查询将从数据库中获取所有其他属性,但您将仅返回用户名。

  • 这将获取数据库的整行,并且 Rails 将实例化完整的模型对象 - 如果您真的只想要名称,那么使用“pluck”或“first”会更有效,正如其他答案所建议的那样。 (4认同)