Reputation: 7835
I have an Array of Contact objects...
[#<Contact id: 371, full_name: "Don Hofton", birthday: "2013-11-07">,...]
And I need to order them by birthdays nearest to the current time AND remove objects from the array that have birthdays greater than 4 months away. Here is what I've got so far, but it's not working....
@contacts_with_birthday_data = Contact.where(:user_id => current_user.id).where("birthday IS NOT NULL")
@current_time = Time.now
@contacts_with_birthday_data.each do |c|
c.birthday = c.birthday[0..4]
c.birthday = Date.parse(c.birthday)
end
@contacts_with_birthday_data = @contacts_with_birthday_data.sort! { |a,b| b[:birthday] <=> a[:birthday] }
@contacts_with_birthday_data = @contacts_with_birthday_data.sort! { |a| a.birthday < DateTime.now }
Upvotes: 0
Views: 2142
Reputation: 1278
I think you can do this all with one query:
Contact \
.where(:user_id => current_user.id)
.where("birthday > ?", 4.months.ago)
.order("birthday desc")
If 4.months.ago
is used in a scope, make sure to wrap it in a lambda or Proc, or it will be calculated when the class is loaded and not on subsequent calls. This has bit me more than once!
Alternatively, in a non-Rails world, you could use the reject
and sort_by
methods on Enumerable:
contacts = [#your array of contacts]
contacts.reject { |c| c.birthday < 4.months.ago }.sort_by(&:birthday).reverse
If you haven't seen the syntax used in sort_by
, that's actually equivalent to sort_by { |c| c.birthday }
. That syntax tells Ruby to convert the birthday method to a Proc object, then call the Proc against each instance in your array.
Upvotes: 1