使用.select或.map从activerecord模型中获取一组名称

时间:2016-01-11 02:32:44

标签: 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 Item.search('ex').map(&:name)

3 个答案:

答案 0 :(得分:8)

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

在上述声明中,您只选择name结果中的Item.search('ex')列,然后使用.map(&:name)获取所有列的名称。

但是,在下面的陈述中:

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

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

是的,他们会返回完全相同的结果。

因此,如果只想从搜索结果中获取名称数组,那么选择名称列是多余的。请坚持下去:

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

或者,甚至更好,使用pluck

Item.search('ex').pluck(:name)

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

答案 1 :(得分:3)

基本上.select所做的是我们所谓的投影,它会过滤查询返回的字段。但是,如果您根本不打电话.select,Rails默认选择表格中的所有字段。

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

答案 2 :(得分:0)

  

第一次查询: Item.search('ex').select('name').map(&: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%')

正如我们可能会看到它在ActiveRecord::Relation中返回Array对象并选择name字段。

立即

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

SELECT `items`.`name` FROM `items` WHERE (lower(name) LIKE '%ex%')

此外,您在#map对象ActiveRecord::Relation上调用了#map方法。

  

Item.search('ex').map(&:name)返回一个新数组,其中包含一次运行块的结果   枚举中的每个元素。

  

第二次查询: SELECT `items`.* FROM `items` WHERE (lower(name) LIKE '%ex%')

#map

您在ActiveRecord::Relation对象上调用ActiveRecord::Relation方法。你进一步说,"嘿ActiveRecord::Relation我只需要搜索对象的名字字段,然后{{1}}重播,以数组的形式提供所有名称。 "

了解更多信息Enumerable Module

希望这有帮助!!!