2017-10-11 38 views
1

我有一个ActiveRecord模型是这样的:如何在Rails 3.x中采集多个属性?

class Person < ActiveRecord::Base 
    attr_accessible :name 
end 

,并需要得到一个哈希映射Personid s到他们的name S:

{1 => "Paul", 2 => "Aliyah", 3 => ... } 

现在,很明显的办法是

Person.all.collect { |p| [p.id, p.name] }.to_h 

但是,我不需要实例化每个Person,我只需要哈希。在Rails 4中,我可以用.pluck(:id, :name)而不是collect,但是在3.x中,pluck只有一个参数。但是我发现这个解决办法得到我想要的东西,而无需加载模型:

Person.all.group(:id).minimum(:name) 

问题:将我烧在地狱?另外,是否有一种更优雅的方式来做到这一点,并且我可能没有意识到这种hacky方法有什么缺点?谢谢!

回答

3

下面是这种情况的一个很好的写起来,各种策略来处理它:Plucking Multiple Columns in Rails 3

我建议的解决方案的偏好有是制作和包括模块:

# multi_pluck.rb 
require 'active_support/concern' 

module MultiPluck 
    extend ActiveSupport::Concern 

    included do 
    def self.pluck_all(relation, *args) 
     connection.select_all(relation.select(args)) 
    end 
    end 
end 
0

,以避免加载的所有对象,你可以这样做:

hash = Hash.new 
ActiveRecord::Base.connection.execute("SELECT id, name FROM persons").each {|person| hash[person['id'].to_s] = person['name'].to_s} 
1
class Person < ActiveRecord::Base 
    attr_accessible :name 

    def self.pluck_id_and_name 
    result = connection.select_all(select(:id, :name)) 
    if result.any? 
     # if you are using Ruby 2.1+ 
     result.to_h 
     # Works in 1.9.3+ 
     Hash[result] 
    end 
    end 
end 

由于结果应该是一个数组的数组,我们可以使用漂亮的手段来得到的散列与第一元件作为键,第二个作为值:

Hash[ [ [1, "Joe"], [2, "Jill"] ] ] 
# => { 1 => "Joe", 2 => "Jill"} 

参见: