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
感谢您的时间!
答案 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
。