未定义的方法`each_with_index'为0:Fixnum

时间:2015-03-24 02:22:29

标签: ruby-on-rails ruby

NoMethodError in Habits#new
where line #29 raised:
<% @habit.levels.each_with_index do |level, index| %>

我们如何删除此错误?

这个想法是用户承诺在某些日子里做他们的积极习惯,但如果他们错过了一天,他们必须在表格中检查它。每天他们都错过了他们必须弥补的一天,然后才能进入下一个级别。

习惯/ _form

    <% @habit.levels.each_with_index do |level, index| %>
  <p>
    <label> Level <%= index + 1 %>: </label>
    <%= f.check_box :missed_one, checked: (level.missed_days > 0) %>
    <%= f.check_box :missed_two, checked: (level.missed_days > 1) %>
    <%= f.check_box :missed_three, checked: (level.missed_days > 2) %>
  </p>
<% end %>

habits.rb

class Habit < ActiveRecord::Base
belongs_to :user
has_many :comments, as: :commentable
has_many :levels
serialize :committed, Array
validates :date_started, presence: true
before_save :set_level
acts_as_taggable
scope :private_submit, -> { where(private_submit: true) }
scope :public_submit, -> { where(private_submit: false) }

attr_accessor :missed_one, :missed_two, :missed_three

def save_with_levels
    self.levels.build
    self.levels.build
    self.levels.build
    self.levels.build
    self.levels.build
    self.save
end

def self.comitted_for_today
today_name = Date::DAYNAMES[Date.today.wday].downcase
ids = all.select { |h| h.committed.include? today_name }.map(&:id)
where(id: ids)
end 

def levels
        return 0 unless date_started #This is the real cause of error, but I need this line to prevent .to_date error from being nil
        committed_wdays = committed.map { |day| Date::DAYNAMES.index(day.titleize) }
        n_days = ((date_started.to_date)..Date.today).count { |date| committed_wdays.include? date.wday }
        actual_days = n_days - self.missed_days

  case n_days     
      when 0..9
        1
      when 10..24
        2
      when 25..44
        3
      when 45..69
        4
      when 70..99
        5
      else
        "Mastery"
    end
end

private
  def set_level
    self.level = levels
  end   
end

感谢您的时间!

2 个答案:

答案 0 :(得分:2)

Habit声明它有许多级别,这意味着你有一个具有Habit外键的类Level。如果不是这种情况,请删除:has_many :levels。但是,如果它违反了案例,那么您将使用def levels

在代码中进一步覆盖它

您的def levels()覆盖返回Fixnum,无法枚举。

答案 1 :(得分:0)

当您尝试加载new模板时,您收到此错误,因为@habit.levels正在返回0而不是可枚举对象。由于您无法迭代Fixnum,因此在进入.each_with_index调用时会抛出异常。在代码中查看此行:

def levels
  return 0 unless date_started
  ...
end

您似乎正在验证date_started的存在,但@habit #levels方法正在返回0

正如ilan berci所指出的,当与.each_with_index链接时,此行总是会失败,因为它被命名为levels但返回Fixnum。但是,回顾一下模型的顶部,您已经在那里声明了has many :levels,它会生成自己的levels方法,该方法将收集与给定{{1}相关联的所有级别并将它们作为可枚举对象返回。

听起来就是基于@habit的使用而发生的事情,但是当您在模型中进一步声明了另一个each_with_index方法时,它会覆盖该方法由levels行给你。如果您确实需要迭代习惯级别的集合,则应更改现在设计为基于值has_many :levels返回levels的自定义Fixnum方法的名称。 n_days