nil的未定义方法`map':NilClass创建表单

时间:2013-03-31 20:33:45

标签: html ruby-on-rails ruby map undefined

我正在尝试为学生创建注册,以便能够注册他们可以使用的部分。但是,当我实际点击创建注册按钮时,我不断收到此错误。当我检查实时shell时,它说@student == nil意味着它没有被正确创建?我对如何解决这个问题感到困惑

<!---REGISTRATION CONTROLLER-->

def new
    @registration = Registration.new
    @student = Student.find(params[:student_id])
    @info = Section.for_rank(@student.rank).for_age(@student.age).map{|s| ["Name: #{Event.find_by_id(s.event.id).name}, 
        Ranks: #{ s.max_rank == nil ? "#{Student::RANKS[s.min_rank-1][0]} and up" : "#{Student::RANKS[s.min_rank-1][0]} - #{Student::RANKS[s.max_rank-1][0]}"},
        Ages: #{ s.max_age == nil ? "#{s.min_age} and up" : "#{s.min_age} - #{s.max_age}" }", s.id] }
end


def create
    @registration = Registration.new(params[:registration])
    if @registration.save
        redirect_to @registration, :notice => "Successful"
    else
        render :action => 'new'
    end
end

<!----MY REGISTRATION FORM -->

<div class="field">
<%= f.hidden_field :student_id, :value => @registration.student_id %>

<div class = "field">
<%= f.select :section_id, options_for_select(@info)%>

<div class="actions">
<%= f.submit nil, :class => 'btn btn-mini'  %></th>

<!--- MY STUDENT SHOW THAT CALLS THE REGISTRATION -->

<%= link_to 'Register ', new_registration_path(:student_id => @student.id), :class => 'btn btn-mini'  %>

1 个答案:

答案 0 :(得分:0)

我不知道你的特定问题的答案是什么,但是这个方法存在问题 - 它在控制器中定义表示,而不是控制器的责任。

无论你想在map街区做什么,都是一团糟。如果出现问题,我几乎可以保证最终会出现问题,那么调试就会变得非常困难。它看起来很复杂,你应该制作一些presenter类来处理选择选项生成,所以你需要做的就是这样:

SectionSelectOptions.new(@student).to_options

SectionSelectOptions类可能是这样的:

class SectionSelectOptions
  attr_reader :student

  def initialize(student)
    raise ArgumentError unless student
    @student = student
  end

  def to_options
    sections.map {|section| SectionOption.new(section, student).to_option }
  end

  private

  def sections
    Section.for_rank(student.rank).for_age(student.age)
  end

end

SectionOption类:

class SectionOption
  attr_reader :section, :student
  def initialize(section, student)
    @section = section
    @student = student
  end

  def to_option
    ["#{name}, #{ranks}, #{ages}", section.id]
  end

  private

  def name
    "Name: #{section.event.name}"
  end

  def ranks
    "..." # I'll let you refactor whatever is going on here
  end

  def ages
    "..."
  end
end

当然,它比为您创建问题的单行代码更长,但这有几个优点:

  1. 它将每一步拆分为它自己的方法,所以当你进行界面更改时,你有一个地方可以改变它(例如,对部分的查找发生变化,你只需更改sections方法)

  2. 通过公共界面或个别方法

  3. 是可测试的
  4. 调试起来比较容易。您现在可以确切地知道出现问题时会发生什么,因为您的错误会告诉您要查看哪种方法。