我正在尝试根据搜索查询从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)
答案 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。
希望这有帮助!!!