按日期排序数组属性,按当前时间排序

时间:2013-09-05 23:38:08

标签: ruby-on-rails ruby

我有一个联系人对象数组......

[#<Contact id: 371, full_name: "Don Hofton", birthday: "2013-11-07">,...]

我需要在离当前时间最近的生日那天订购它们并从数组中删除生日超过4个月的对象。这是我到目前为止所得到的,但它不起作用......

@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 }

1 个答案:

答案 0 :(得分:1)

我认为您可以通过一个查询完成所有操作:

Contact \
  .where(:user_id => current_user.id)
  .where("birthday > ?", 4.months.ago)
  .order("birthday desc")

如果在作用域中使用4.months.ago,请确保将其包装在lambda或Proc中,否则将在加载类时计算,而不是在后续调用中计算。这让我不止一次!

或者,在非Rails世界中,您可以在Enumerable上使用rejectsort_by方法:

contacts = [#your array of contacts]
contacts.reject { |c| c.birthday < 4.months.ago }.sort_by(&:birthday).reverse

如果您还没有看到sort_by中使用的语法,那实际上等同于sort_by { |c| c.birthday }。该语法告诉Ruby将生日方法转换为Proc对象,然后针对数组中的每个实例调用Proc。