选择特定属性

时间:2016-02-10 16:42:16

标签: ruby-on-rails ruby

#<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

4 个答案:

答案 0 :(得分: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月将在索引1处。)

然后:

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

P.S。如果您希望使用散列而不是数组,则可以使用ActiveSupport中的Hash#slice

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只返回这些属性的值,而不是实例化并返回Example模型对象。

答案 1 :(得分:0)

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

答案 2 :(得分: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?)

答案 3 :(得分: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]