Ruby on rails 使用.select或.map从activerecord模型获取名称数组
我试图从基于搜索查询的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
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吗