Reputation: 357
#<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>
I want to put the values of months in a array like this:
array_example = [12, 3, 3, 4, 5, 2, 4, 24, 4, 24, 4, 4]
I know I can do this (example below) but I want a better way.
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
Upvotes: 0
Views: 1081
Reputation: 106027
Hash#values_at
is for exactly this:
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]
It's probably best to put the month names in a constant (e.g. in your Example model), if only for readability, e.g.:
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 }
(The latter uses Ruby's built-in Date::MONTHNAMES
constant; drop(1)
is necessary because Date::MONTHNAMES[0]
is nil
, presumably so January will be at index 1.)
Then:
example.attributes.values_at(*Example::MONTH_ATTRS)
P.S. If you would rather have a hash than an array, you can use Hash#slice
from 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. If you're not using the model object for anything else—i.e. you just want the month values and nothing else, you should use ActiveRecord::Calculations#pluck
in your query, e.g.:
Example.where(...).pluck(*Example::MONTH_ATTRS)
pluck
tells ActiveRecord to just return the values of those attributes, instead of instantiating and returning an Example model object.
Upvotes: 1
Reputation: 6707
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]
Upvotes: 0
Reputation: 32933
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?)
Upvotes: 0