Ruby on rails Rails 3-未定义的方法'map';for nil:NilClass用于我自己的验证
我遇到了一个很奇怪的问题。我有Ruby on rails Rails 3-未定义的方法'map';for nil:NilClass用于我自己的验证,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,我遇到了一个很奇怪的问题。我有时间表模型,并尝试编写自定义验证。所以,现在我只是尝试为字段添加测试错误,以确保一切正常。但它不起作用。所以,我尝试更新时间表模型的对象,但当我不使用我的测试自定义验证时,一切都很完美。否则我会得到这样的错误: NoMethodError in Timetables#update undefined method `map' for nil:NilClass 32: 33: <div class="controls"> 34:
时间表
模型,并尝试编写自定义验证。所以,现在我只是尝试为字段添加测试错误,以确保一切正常。但它不起作用。所以,我尝试更新时间表模型的对象,但当我不使用我的测试自定义验证时,一切都很完美。否则我会得到这样的错误:
NoMethodError in Timetables#update
undefined method `map' for nil:NilClass
32:
33: <div class="controls">
34: <%= f.select( :curriculum_id,
35: options_for_select( @subjects_with_curriculums,
36: @tt.curriculum_id ),
37: { :include_blank => true }) %>
38: </div>
NoMethodError在时间表中#更新
nil:NilClass的未定义方法“map”
32:
33:
34:正确})%>
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 < ActiveRecord::Base
belongs_to :curriculum
belongs_to :school_class
has_many :lessons
validates :school_class_id, :presence => { :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
#==架构信息
#
#表名:时间表
#
#id:整数不为空,主键
#课程号:整数
#学校\班级\ id:整数
#每周的tt天:字符串(255)
#第一课:整数
#tt_房间:字符串(255)
#tt_类型:字符串(255)
#创建时间:datetime非空
#更新时间:datetime非空
#
课程时间表{:message=>“应该存在”}
验证:tt_day_of_week,
:presence=>true,
:inclusion=>{:in=>%w(周一周二周三周四周五)}
验证:TTU课程的TTU编号,
:presence=>true,
:包含=>{
:in=>1..9,
:message=>“应该有1..9个符号”
}
验证:tt_室,
:长度=>{
:最大=>3,
:message=>“应该有3个符号”
},
:allow_blank=>true
验证:tt_类型,
:inclusion=>{:in=>[“初级课程”,“额外”]},
:allow_blank=>true
验证:测试
def测试
错误。添加(:tt_课程编号“测试”)
结束
结束
我的控制器:
# encoding: UTF-8
class TimetablesController < ApplicationController
...
def edit
@types_of_lesson = collect_types_of_lesson
@tt = Timetable.find( params[:id] )
@subjects_with_curriculums = collect_subjects_with_curriculums( @tt.school_class )
end
def update
@tt = Timetable.find( params[:id] )
if @tt.update_attributes( params[:timetable] )
flash[:success] = "Расписание успешно обновлено!"
redirect_to timetables_path
else
flash.now[:error] = @tt.errors.full_messages.to_sentence :last_word_connector => ", ",
: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
render 'edit'
编码:UTF-8
类TimetablesController<应用程序控制器
...
定义编辑
@课程类型=收集课程类型
@tt=时间表。查找(参数[:id])
@课程科目=收集课程科目(@tt.school\u class)
结束
def更新
@tt=时间表。查找(参数[:id])
if@tt.update_属性(参数[:时间表])
flash[:success]=“аааааааааааааааа
将\u重定向到时间表\u路径
其他的
flash.now[:error]=@tt.errors.full_messages.to_句子:last_word_connector=>“,”,
:两个单词\u连接器=>“,”
渲染“编辑”
结束
结束
私有的
#收集学校班级的科目名称和每个科目的课程id。
def收集课程中的科目(学校课程)
科目=学校|班级.课程.收集do | c|
[c.qualification.subject.subject_姓名,c.id]
结束
结束
带有现有数据的班级的def时间表(学校班级)
如果timeline.all.empty为空,返回[]?
时间表。选择do | t|
(t.school_class.class_code==school_class.class_code)和
非(t.tt_房间空白?)和非(t.tt_类型空白?)和
不是(t.课程\ id.无?)
完
结束
#上课时间到了。
def课程时间表(学校课程)
时间表。选择{t | t.school|u class.class_code==school|u class.class_code}。到
结束
def课程(学校课程)
科目=学校|班级.课程.收集do | c|
c、 资格、科目、科目名称
结束
结束
#返回按一天可编辑的课程数排序的结果。
def分拣的日时间表(时间表,日)
时间表。选择{t | t.tt_day_of_week==day}
.sort_by{e|e[:tt_number_of_lesson]}
结束
#返回课程类型的俄语名称。
def收集课程的类型
[“初级课程”]、[“额外课程”]
结束
#检查是否已经为学校班级创建了时间表。
是否存在def时间表?(学校/班级)
没有上课时间表(学校课)。空吗?
结束
结束
我的看法
<%= form_for @tt, :html => {:class => "form-horizontal"} do |f| %>
<%= field_set_tag do %>
<%= f.hidden_field :tt_number_of_lesson %>
<%= f.hidden_field :tt_day_of_week %>
<%= f.hidden_field :school_class_id %>
<div class="control-group">
<%= f.label :tt_day_of_week, "Day of the week", :class => "control-label" %>
<div class="controls">
<%= content_tag( :span, translate_day_of_week( @tt.tt_day_of_week ),
:class =>"input-xlarge uneditable-input span2" ) %>
</div>
</div>
<div class="control-group">
<%= f.label :tt_number_of_lesson, "Number of lesson", :class => "control-label" %>
<div class="controls">
<%= content_tag( :span, @tt.tt_number_of_lesson,
:class =>"input-xlarge uneditable-input span1" ) %>
</div>
</div>
<hr/>
<div class="control-group">
<%= f.label :curriculum_id, "Type of subject", :class => "control-label" %>
<div class="controls">
<%= f.select( :curriculum_id,
options_for_select( @subjects_with_curriculums,
@tt.curriculum_id ),
{ :include_blank => true }) %>
</div>
</div>
<div class="control-group">
<%= f.label :tt_room, "Code of the room", :class => "control-label" %>
<div class="controls">
<%= f.text_field :tt_room, :class => "span2", :maxlength => 3 %>
</div>
</div>
<div class="control-group">
<%= f.label :tt_type, "Type of the lesson", :class => "control-label" %>
<div class="controls">
<%= f.select( :tt_type,
options_for_select( @types_of_lesson,
@tt.tt_type ),
{ :include_blank => true }) %>
</div>
</div>
<%= f.submit "Update", :class => "btn btn-large btn-warning" %>
<% end %>
<% end %>
{:class=>“水平形式”}do | f |%>
“控制标签”%>
“输入xlarge不可编辑输入span2”)%%>
“控制标签”%>
“输入xlarge不可编辑的输入span1”)%%>
“控制标签”%>
真})%%>
“控制标签”%>
“span2”,:maxlength=>3%>
“控制标签”%>
真})%%>
“btn btn大型btn警告”%>
当我删除:
<div class="control-group">
<%= f.label :curriculum_id, "Type of subject", :class => "control-label" %>
<div class="controls">
<%= f.select( :curriculum_id,
options_for_select( @subjects_with_curriculums,
@tt.curriculum_id ),
{ :include_blank => true }) %>
</div>
</div>
<div class="control-group">
<%= f.label :tt_type, "Type of the lesson", :class => "control-label" %>
<div class="controls">
<%= f.select( :tt_type,
options_for_select( @types_of_lesson,
@tt.tt_type ),
{ :include_blank => true }) %>
</div>
</div>
“控制标签”%>
真})%%>
“控制标签”%>
真})%%>
我可以查看我的测试错误。我想不出发生了什么事。你在
更新中这样说控制器:
# encoding: UTF-8
class TimetablesController < ApplicationController
...
def edit
@types_of_lesson = collect_types_of_lesson
@tt = Timetable.find( params[:id] )
@subjects_with_curriculums = collect_subjects_with_curriculums( @tt.school_class )
end
def update
@tt = Timetable.find( params[:id] )
if @tt.update_attributes( params[:timetable] )
flash[:success] = "Расписание успешно обновлено!"
redirect_to timetables_path
else
flash.now[:error] = @tt.errors.full_messages.to_sentence :last_word_connector => ", ",
: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
render 'edit'
这只是告诉Rails呈现编辑模板,它不运行与edit
控制器关联的任何代码,它只是在当前上下文中呈现edit.html.erb
从:
2.2.2呈现动作视图
[关于render'x'
,render:x
,和render:action=>:x
相同的一些东西…]
将渲染
与:操作
一起使用,经常会使Rails新手感到困惑。指定的操作用于确定要渲染的视图,但Rails不会在控制器中运行该操作的任何代码。在调用render
之前,必须在当前操作中设置视图中需要的任何实例变量
特别注意最后一句话