【问题标题】:Undefined Method Error When Calling .sort_by on Second Array在第二个数组上调用 .sort_by 时出现未定义的方法错误
【发布时间】:2016-06-09 21:47:40
【问题描述】:

我有一个包含两个日期列的联系人模型。在这种情况下生日和family_anniversary。当我在查询中调用 .sort_by 以提取未来 90 天内的日期时,我收到以下错误。

错误: undefined method 'birthday_within_90_days' for #<Array:0x007f934fff1dd0>

疑难解答: 我在每次通话时都注释掉了 .sort_by ,当我这样做时,其他的工作。我能弄清楚的最好的是这与 ActiveRecord 和数组有关。我怀疑我无法对从同一模型中提取的两个数组进行排序。但是我是新手,这是一个我完全不了解的领域。

我的 Model 代码,请注意我使用的是 RailsLove/birthday gem,这是我获得 find_#{column_name}_for 方法的地方。

def next_birthday
  year = Date.today.year
  mmdd = birthday.strftime('%m%d')
  year += 1 if mmdd < Date.today.strftime('%m%d')
  mmdd = '0301' if mmdd == '0229' && !Date.parse("#{year}0101").leap?
  return Date.parse("#{year}#{mmdd}")
end

def next_anniversary
  year = Date.today.year
  mmdd = family_anniversary.strftime('%m%d')
  year += 1 if mmdd < Date.today.strftime('%m%d')
  mmdd = '0301' if mmdd == '0229' && !Date.parse("#{year}0101").leap?
  return Date.parse("#{year}#{mmdd}")
end

def self.anniversary_within_90_days
  find_family_anniversaries_for((Date.today), (Date.today + 90.days)).sort_by(&:next_anniversary)
end

def self.birthday_within_90_days
  find_birthdays_for((Date.today), (Date.today + 90.days)).sort_by(&:next_birthday)
end

我意识到这不是 DRY。这将是一个不同的问题。

我的控制器代码是:

def dates
  @user = current_user
  contact_ids = @user.contacts.pluck(:id)

  @contacts = Contact
  @contacts = @contacts.where(id: contact_ids.uniq)
  @contacts = @contacts.anniversary_within_90_days
  @contacts = @contacts.birthday_within_90_days
  @children = @user.children
  @pets     = @user.pets
end

我的查看代码:

<div data-equalizer class="row">
  <div data-equalizer-watch class="small-12 medium-3 columns">
    <%= render "layouts/sidenav" %>
  </div>
  <div data-equalizer-watch class="medium-9 columns contacts-list show-for-medium-up">
    <ul style="list-style:none;">
      <li>
        <h3>Birthdays in the next 90 Days</h3>
         <% @contacts.each do |contact| %>
          <ul style="list-style:none;">
            <% if contact.birthday.present? %>
              <%= link_to "#{contact.first_name} #{contact.last_name}", contact %> <strong><%= contact.birthday.try(:strftime, "%m/%d/%Y") %></strong> (<%= contact.birthday_age %> years old)
            <% end %>
          </ul>
        <% end %>
      </li>
      <li>
    <h3>Children's Birthdays in the next 90 Days</h3>
    <% @children.each do |child| %>
      <ul style="list-style:none;">
       <% if child.child_birthday.present? %>
        <%= child.name %> <strong><%= child.child_birthday.try(:strftime, "%m/%d/%Y") %></strong> (<%= child.child_birthday_age %> years old)
      <% end %>
      </ul>
    <% end %>
  </li>
  <li>
    <h3>Anniversaries in the next 90 Days</h3>
    <% @contacts.each do |contact| %>
      <ul style="list-style:none;">
        <% if contact.family_anniversary.present? %>
            <%= link_to "#{contact.first_name} #{contact.last_name}", contact %> <strong><%= contact.family_anniversary.try(:strftime, "%m/%d/%Y") %></strong> has been married for <%= contact.family_anniversary_age %> years.
            <% end %>
          </ul>
        <% end %>
      </li>
      <li>
        <h3>Pets Born in the next 90 Days</h3>
        <% @pets.each do |pet| %>
          <ul style="list-style:none;">
            <% if pet.birthday.present? %>
              <%= pet.name %> <strong><%=pet.birthday.try(:strftime, "%m/%d/%Y") %></strong> (<%= pet.birthday_age %> years old)
            <% end %>
          </ul>
        <% end %>
      </li>
    </ul>
  </div>
</div>

感谢任何有关如何解决此问题的提示。

【问题讨论】:

  • 正如我在回答中所描述的那样。但要说清楚 - 删除自我,因为您将该方法称为实例方法。

标签: ruby-on-rails arrays ruby ruby-on-rails-4 activerecord


【解决方案1】:

不要做我做过的事

这是很臭的代码,从长远来看会表现不佳。由于应用程序中有许多日期分布在多个关系中,因此最好使用单表继承来提高运行查找和排序时的性能。

【讨论】:

    【解决方案2】:

    你知道什么时候使用类和实例方法吗?

    @contact = Contact.first # creates an instance of Contact
    @contact.birthday_within_90_days
    
    class Contact
      def birthday_within_90_days
        ..
      end
    end 
    

    有效。

    您编写并使用以下代码的 as Class 方法

    @contacts = Contact.birthday_within_90_days
    
    class Contact
      def self.birthday_within_90_days
        ...
      end
    end
    

    【讨论】:

    • 感谢@devanand 的澄清。我使用了 Class 方法,它导致错误消失,但它显示了所有联系人的所有值,而不仅仅是用户联系人。第二个列表仍未排序。我使用了 Instance 方法(我认为这是正确的方向),我得到了undefined method 'anniversary_within_90_days' for #&lt;Contact::ActiveRecord_Relation:0x007ff69e5028e0&gt;,所以我的模型中的方法没有通过。
    猜你喜欢
    • 1970-01-01
    • 2011-06-16
    • 2016-07-05
    • 2019-09-02
    • 1970-01-01
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多