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

Using .select or .map to get an array of names from an activerecord model

我正在尝试根据搜索查询从 activerecord 模型中获取一组名称。

我的物品模型中有这个方法。

def self.search(search)
    if search
      where(['lower(name) LIKE ?', "%#{search}%"])
    else
      Item.all
    end
  end

我想找出使用​​这两条线的区别,它们都返回相同的东西。

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

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

在上面的语句中,您仅从 Item.search('ex') 的结果中选择 name 列,然后使用 .map(&:name).[=23= 获取所有列的名称]

但是,在下面的语句中:

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

您没有选择 name 列,只是使用 .map(&:name)Item.search('ex').

的结果中获取名称

是的,他们 return 结果完全相同。

因此,如果您只想从搜索结果中获取姓名数组,那么选择姓名列是多余的。就这样吧:

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

或者,更好的是,使用 pluck:

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

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

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

中的所有字段

所以Item.search('ex').select('name')Item.search('ex')的区别在于前者只选择name列而后者选择[=]中的所有列18=]项table。 鉴于此,当您映射所有项目以仅获取名称时,它没有任何区别,因为两种方式都选择了 name

1st Query: 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%')

正如我们可能看到的那样 return ActiveRecord::Relation Array 中的对象选择了 name 个字段。

现在

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

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

进一步,当您在 ActiveRecord::Relation 对象上调用 #map 方法时,该对象本身在 Enumerable Module 中定义。

#map Returns a new array with the results of running block once for every element in enum.


2nd Query: Item.search('ex').map(&:name)

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

此处您在 ActiveRecord::Relation 对象上调用 #map 方法。你还说,“嘿 ActiveRecord::Relation 我只需要来自搜索对象的名称字段,然后 ActiveRecord::Relation 重播以数组形式给出所有名称。“

更多信息The clever hack that makes items.map(&:name) work

希望对您有所帮助!!!