2016-02-10 128 views
0
#<Example example_id: 13, example2_id: 81, year: 2000, january: 12, february: 3, march: 3, april: 4, may: 5, june: 2, july: 4, august: 24, september: 4, october: 24, november: 4, december: 4> 

我想把几个月的价值观像这样的数组:选择特定的属性

array_example = [12, 3, 3, 4, 5, 2, 4, 24, 4, 24, 4, 4] 

我知道我能做到这一点(下面的例子),但我希望有一个更好的办法。

example.attributes.each do |attr_name, attr_value| 
     if attr_name == "january" || attr_name == "february" || attr_name == "march" || 
     attr_name == "april" || attr_name == "may" || attr_name == "june" || 
     attr_name == "july" || attr_name == "august" || attr_name == "september" || 
     attr_name == "october" || attr_name == "november" || attr_name == "december" 
        @array_example << attr_value 
     end 
    end 

回答

1

Hash#values_at是正是这一点:

example.attributes.values_at(:january, :february, :march, :april, :may, :june, :july, :august, :september, :october, :november, :december) 
# => [12, 3, 3, 4, 5, 2, 4, 24, 4, 24, 4, 4] 

这也可能是最好把月份名称在恒定(例如,在你的榜样模型),如果仅用于可读性,例如:

MONTH_ATTRS = %i[ january february march  april 
        may  june  july  august 
        september october november december ] 
# Or... 
MONTH_ATTRS = Date::MONTHNAMES.drop(1).map {|m| m.downcase.to_sym } 

(后者使用Ruby的内置Date::MONTHNAMES常量; drop(1)是必要的,因为Date::MONTHNAMES[0]nil,想必所以一月将索引1)

然后:

example.attributes.values_at(*Example::MONTH_ATTRS) 

附:如果你宁愿有一个哈希不是一个数组,你可以使用Hash#slice从的ActiveSupport:

example.attributes.slice(*Example::MONTH_ATTRS) 
# => { :january => 12, :february => 3, :march => 3, :april => 4, 
#  :may => 5,  :june => 2,  :july => 4,  :august => 24, 
#  :september => 4, :october => 24, :november => 4, :december => 4 } 

P.P.S.如果你不使用模型对象进行其他任何事情 - 例如。你只是想月份值,没有别的,你应该在你的查询中使用ActiveRecord::Calculations#pluck,例如:

Example.where(...).pluck(*Example::MONTH_ATTRS) 

pluck告诉ActiveRecord的,只是返回,而不是实例化和返回为例模型对象的属性值。

0
months = %w(january february march) 
months.include? attr_name 
+0

作为它的每一个月份的名称可能是最容易使用日期的月份名称不变'个月=日期:: MONTHNAMES.reject。(:无)地图(:downcase)' –

0
monthnames = %w(january february march april may june july august september october november december) 
example_attributes.each do |attr_name, attr_value| 
    if monthnames.include?(attr_name) 
    @array_example << attr_value 
    end 
end 

OR

@array_example += monthnames.collect{|monthname| example.attributes[monthname]}.reject(&:blank?) 
0
MONTHS = %w(january february march april may june july august september october november december) 

example.attributes.slice(*MONTHS) 
=> {january: 12, february: 3, march: 3, april: 4, may: 5, june: 2, july: 4, august: 24, september: 4, october: 24, november: 4, december: 4} 
example.attributes.slice(*MONTHS).values 
=> [12, 3, 3, 4, 5, 2, 4, 24, 4, 24, 4, 4] 
相关问题