Ruby on rails 使用.select或.map从activerecord模型获取名称数组

Ruby on rails 使用.select或.map从activerecord模型获取名称数组,ruby-on-rails,ruby,ruby-on-rails-3,ruby-on-rails-4,activerecord,Ruby On Rails,Ruby,Ruby On Rails 3,Ruby On Rails 4,Activerecord,我试图从基于搜索查询的activerecord模型中获取名称数组 我在我的项目模型中有这个方法 def self.search(search) if search where(['lower(name) LIKE ?', "%#{search}%"]) else Item.all end end 我试图找出使用这两行的区别,它们都返回相同的内容 Item.search('ex')。select('name')。map(&:name)vs It

我试图从基于搜索查询的activerecord模型中获取名称数组

我在我的项目模型中有这个方法

def self.search(search)
    if search
      where(['lower(name) LIKE ?', "%#{search}%"])
    else
      Item.all
    end
  end
我试图找出使用这两行的区别,它们都返回相同的内容

Item.search('ex')。select('name')。map(&:name)
vs
Item.search('ex').map(&:name)

在上面的语句中,您仅从
项的结果中选择
名称
列。搜索('ex')
,然后使用
.map(&:name)
获取所有项的名称

但是,在下面的声明中:

Item.search('ex').map(&:name)
您没有选择
name
列,只是使用
.map(&:name)
项的结果中获取名称。搜索('ex')

是的,它们返回完全相同的结果

因此,如果只希望从搜索结果中获得名称数组,那么选择名称列是多余的。就这么说吧:

Item.search('ex').map(&:name)
或者,更好的做法是,使用:

它不需要实例化每个
ActiveRecord
对象,而是直接返回
Array
中的查询值,从而提高了执行时间和内存消耗方面的性能

在上面的语句中,您仅从
项的结果中选择
名称
列。搜索('ex')
,然后使用
.map(&:name)
获取所有项的名称

但是,在下面的声明中:

Item.search('ex').map(&:name)
您没有选择
name
列,只是使用
.map(&:name)
项的结果中获取名称。搜索('ex')

是的,它们返回完全相同的结果

因此,如果只希望从搜索结果中获得名称数组,那么选择名称列是多余的。就这么说吧:

Item.search('ex').map(&:name)
或者,更好的做法是,使用:


它绕过了实例化每个
ActiveRecord
对象的需要,而是直接返回
数组中的查询值,这在执行时间和内存消耗方面都提高了性能。

基本上
。select
就是我们所说的投影,这将筛选查询返回的字段。但是,如果您根本不调用
.select
,Rails默认从表中选择所有字段

因此
Item.search('ex').select('name')
Item.search('ex')
之间的区别在于前者只选择name列,后者选择items表中的所有列。
有鉴于此,当您映射所有项目以仅获取名称时,它不会产生任何差异,因为这两种方法都选择了名称

基本上
。选择
所做的就是我们称之为投影,它过滤查询返回的字段。但是,如果您根本不调用
.select
,Rails默认从表中选择所有字段

因此
Item.search('ex').select('name')
Item.search('ex')
之间的区别在于前者只选择name列,后者选择items表中的所有列。 有鉴于此,当您映射所有项目以仅获取名称时,不会产生任何差异,因为这两种方式都选择了名称

第一次查询:
项。搜索('ex')。选择('name')。映射(&:name)

让我们一件一件地看一下整个陈述

Item.search('ex') # it trigger one SQL query and return `ActiveRecord::Relation` object in Array

 SELECT `items`.* FROM `items` WHERE (lower(name) LIKE '%ex%')
下一步

Item.search('ex').select('name')
 SELECT `items`.`name` FROM `items` WHERE (lower(name) LIKE '%ex%')
正如我们可能看到的,它通过选择
name
字段返回
ActiveRecord::Relation
数组中的对象

现在

Item.search('ex').select('name').map(&:name)

SELECT `items`.`name` FROM `items` WHERE (lower(name) LIKE '%ex%')
在这里,当您调用在中定义的
ActiveRecord::Relation
对象上的
#map
方法时

#map
返回一个新数组,其中包含运行block一次的结果 枚举中的每个元素


第二次查询:
Item.search('ex').map(&:name)

这里您正在调用
ActiveRecord::Relation
对象上的
#map
方法。进一步说,“嘿
ActiveRecord::Relation
我只需要搜索对象中的name字段,然后
ActiveRecord::Relation
回放以数组的形式给出所有名称。”

了解更多信息

希望这有帮助

第一次查询:
项。搜索('ex')。选择('name')。映射(&:name)

让我们一件一件地看一下整个陈述

Item.search('ex') # it trigger one SQL query and return `ActiveRecord::Relation` object in Array

 SELECT `items`.* FROM `items` WHERE (lower(name) LIKE '%ex%')
下一步

Item.search('ex').select('name')
 SELECT `items`.`name` FROM `items` WHERE (lower(name) LIKE '%ex%')
正如我们可能看到的,它通过选择
name
字段返回
ActiveRecord::Relation
数组中的对象

现在

Item.search('ex').select('name').map(&:name)

SELECT `items`.`name` FROM `items` WHERE (lower(name) LIKE '%ex%')
在这里,当您调用在中定义的
ActiveRecord::Relation
对象上的
#map
方法时

#map
返回一个新数组,其中包含运行block一次的结果 枚举中的每个元素


第二次查询:
Item.search('ex').map(&:name)

这里您正在调用
ActiveRecord::Relation
对象上的
#map
方法。进一步说,“嘿
ActiveRecord::Relation
我只需要搜索对象中的name字段,然后
ActiveRecord::Relation
回放以数组的形式给出所有名称。”

了解更多信息


希望这有帮助

你也可以用勇气。当然,蒂姆。我想你是在我编辑我的答案并添加
pluck
:)比赛条件时发表评论的。。我认为你是第一个提出这个建议的人,这是一个好主意answer@Drenmi我不太明白为什么有勇气。搜索不需要遍历所有对象才能找到m吗