In order to keep things simple I have avoided using an enum for an attribute, and am instead storing string values.
I have a list of all possible values in a predetermined order in the array: MyTypeEnum.names
And I have an ActiveRecord::Relation list of records in my_recs = MyModel.order(:my_type)
What is the best way to order records in my_recs by their :my_type attribute value in the order specified by the array of values in MyTypeEnum.names ?
I could try this:
my_recs = MyModel.order(:my_type)
ordered_recs = []
MyTypeEnum.names.each do |my_type_ordered|
ordered_recs << my_recs.where(:my_type => my_type_ordered)
end
But am I killing performance by building an array instead of using the ActiveRecord::Relation? Is there a cleaner way? (Note: I may want to have flexibility in the ordering so I don't want to assume the order is hardcoded as above by the order of MyTypeEnum.names)
You are definitely taking a performance hit by doing a separate query for every item in MyTypeEnum
. This requires only one query (grabbing all records at once).
ordered_recs = Hash[MyTypeEnum.names.map { |v| [v, []] }]
MyModel.order(:my_type).all.each do |rec|
ordered_recs[rec.my_type] << rec
end
ordered_recs = ordered_recs.values.flatten
If MyTypeEnum
contains :a
, :b
, and :c
, ordered_recs
is initialized with a Hash
of Arrays
keyed by each of the above symbols
irb(main):002:0> Hash[MyTypeEnum.names.map { |v| [v, []] }]
=> {:a=>[], :b=>[], :c=>[]}
The records are appended to the proper Array
based on it's key in the Hash
, and then when all have bene properly grouped, the arrays are concatenated/flattened together into a single list of records.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.