Rails 3 – nil的未定义方法`map’:NilClass用于我自己的validation

我遇到了很奇怪的问题。 我有Timetable模型,并尝试编写我的自定义validation。 所以,现在我只是想为字段添加测试错误,以确保一切正常。 但它不起作用。 所以,我尝试更新时间表模型的对象,但是当我不使用我的测试自定义validation时,一切都很完美。 否则我得到这样的错误:

 NoMethodError in Timetables#update undefined method `map' for nil:NilClass 32: 33: 
34: true }) %> 38:

这是我的模型:

 # == Schema Information # # Table name: timetables # # id :integer not null, primary key # curriculum_id :integer # school_class_id :integer # tt_day_of_week :string(255) # tt_number_of_lesson :integer # tt_room :string(255) # tt_type :string(255) # created_at :datetime not null # updated_at :datetime not null # class Timetable  { :message => "should exist" } validates :tt_day_of_week, :presence => true, :inclusion => { :in => %w(Mon Tue Wed Thu Fri) } validates :tt_number_of_lesson, :presence => true, :inclusion => { :in => 1..9, :message => "should have 1..9 symbols" } validates :tt_room, :length => { :maximum => 3, :message => "should have 3 symbols" }, :allow_blank => true validates :tt_type, :inclusion => { :in => ["Primary lesson", "Extra"] }, :allow_blank => true validate :test def test errors.add(:tt_number_of_lesson, "test") end end 

我的控制器:

 # encoding: UTF-8 class TimetablesController  ", ", :two_words_connector => ", " render 'edit' end end private # Collecting subjects names for school class and curriculum_id for each subject. def collect_subjects_with_curriculums( school_class ) subjects = school_class.curriculums.collect do |c| [ c.qualification.subject.subject_name, c.id ] end end def timetable_for_class_with_existance_data( school_class ) return [] if Timetable.all.empty? Timetable.select do |t| ( t.school_class.class_code == school_class.class_code ) and not ( t.tt_room.blank? ) and not ( t.tt_type.blank? ) and not ( t.curriculum_id.nil? ) end.to_a end # Return for school class it's timetable. def timetable_for_class( school_class ) Timetable.select{|t| t.school_class.class_code == school_class.class_code }.to_a end def subjects_of_class( school_class ) subjects = school_class.curriculums.collect do |c| c.qualification.subject.subject_name end end # Return sorted by number of lesson tometable for one day. def sorted_timetable_for_day( timetable, day ) timetable.select{ |t| t.tt_day_of_week == day } .sort_by{ |e| e[:tt_number_of_lesson] } end # Return russian name for type of lesson. def collect_types_of_lesson [ ["Обязательно занятие", "Primary lesson"], ["Электив", "Extra"] ] end # Check if timetable already has been created for school class. def timetable_exists?( school_class ) not timetable_for_class( school_class ).empty? end end 

我的看法

  {:class => "form-horizontal"} do |f| %>     
"control-label" %>
"input-xlarge uneditable-input span2" ) %>
"control-label" %>
"input-xlarge uneditable-input span1" ) %>

"control-label" %>
true }) %>
"control-label" %>
"span2", :maxlength => 3 %>
"control-label" %>
true }) %>
"btn btn-large btn-warning" %>

当我删除:

 
"control-label" %>
true }) %>
"control-label" %>
true }) %>

我可以查看我的测试错误。 我无法弄清楚发生了什么。

你在update控制器中这样说:

 render 'edit' 

这只是告诉Rails渲染编辑模板,它不运行任何与edit控制器关联的代码,它只是在当前上下文中呈现edit.html.erb

从Rails指南中的布局和渲染 :

2.2.2渲染动作视图
[关于render 'x'一些东西, render :xrender :action => :x是相同的…]

使用render with :action是Rails新手的常见混淆源。 指定的操作用于确定要呈现的视图,但Rails不会在控制器中运行该操作的任何代码。 在调用render之前,必须在当前操作中设置视图中所需的任何实例变量。

特别注意最后一句话:

在调用render之前,必须在当前操作中设置视图中所需的任何实例变量。

您正在edit控制器中设置@subjects_with_curriculums ,但使用update控制器中的edit视图。 结果是当edit.html.erb尝试在update尝试呈现编辑视图时尝试使用@subjects_with_curriculumsnil

您需要在update控制器中设置@subjects_with_curriculums ,您可能还需要@types_of_lesson