使用 .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。
希望对您有所帮助!!!
我正在尝试根据搜索查询从 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。
希望对您有所帮助!!!