Rails未定义的方法' map'为零:NilClass

时间:2014-08-05 19:16:24

标签: ruby-on-rails-3

当我尝试从嵌套表单创建新记录时,我收到此消息。奇怪的是,当我只是退回到上一页(带有'创建'按钮的页面)并再次点击'创建'时,就会创建记录。因此我不确定为什么它不会在第一次和第二次按下按钮时在我的控制器中更改创建方法时第一次不创建记录。任何人在此之前都会遇到这种情况可以帮助我理解为什么会发生这种情况会很棒。

模型

class Benefit < ActiveRecord::Base
  belongs_to :account
  has_many :employee_benefits
  has_many :benefit_plans, :inverse_of => :benefit   
  belongs_to :benefit_coverage_period
  belongs_to :benefit_type_id, :class_name => "LookupTable", :foreign_key => "benefit_type"

  attr_accessible :account_id, :active, :attachment, :automatic_rollover, :id, :benefit_id, :benefit_type_id 
  attr_accessible :benefit_coverage_id, :benefit_type, :is_pretax, :benefit_coverage_period_id
  attr_accessible :description, :enrollable, :link, :name, :has_plans, :has_custom_amount, :benefit_plans_attributes

  validates_format_of :link, :message => "Please enter a valid URL", :with => /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix

  accepts_nested_attributes_for :benefit_plans, allow_destroy: true
end

class BenefitPlan < ActiveRecord::Base
  belongs_to :benefit, :inverse_of => :benefit_plans
  validates_presence_of :benefit
  has_many :employee_benefits
  has_many :benefit_coverages

  attr_accessible :benefit_id, :description, :name, :benefit_coverages_attributes, :link, :attachment

  accepts_nested_attributes_for :benefit_coverages, allow_destroy: true
end

class BenefitCoverage < ActiveRecord::Base
  belongs_to :benefit_plan  
  has_many :employee_benefits
  belongs_to :name_id, :class_name => "LookupTable", :foreign_key => "name"

  attr_accessible :benefit_plan_id, :name, :paycheck_deduction, :percentage_split, :total_cost

  accepts_nested_attributes_for :employee_benefits
end

控制器

def new
  @benefit = Benefit.new
  @benefit_coverage_periods = @account.benefit_coverage_periods
  1.times { @benefit.benefit_plans.build(:name => 'Default Plan') }
  @lookup_tables = LookupTable.where(:active => :true).find_all_by_group(30) || []
  @lookup_tables1 = LookupTable.where(:active => :true).find_all_by_group(31) || []
end

def create
  @benefit = Benefit.new(params[:benefit])
  @lookup_tables = LookupTable.where(:active => :true).find_all_by_group(30) || []
  @lookup_tables1 = LookupTable.where(:active => :true).find_all_by_group(31) || []
  @benefit_coverage_periods = @account.benefit_coverage_periods

  if @benefit.save
    redirect_to benefits_path, :notice => 'Benefit was successfully created.'
  else
    render :action => "new"
end

查看

= form_for @benefit, :html => { :class => "form-horizontal" }, :validate => true do |f|
  = f.hidden_field :account_id, :value => @account.id
  .control-group
    = f.label :name, :class => "control-label"
    .controls
      = f.text_field :name, :class => "text_field"
  .control-group
    = f.label :benefit_type, "Benefit Type", :class => "control-label"
    .controls
      = f.collection_select :benefit_type, @lookup_tables1, :id, :title, :prompt => true
...

错误

NoMethodError - undefined method `map' for nil:NilClass:
15:00:09 web.1   |   actionpack (3.2.14)                   lib/action_view/helpers/form_options_helper.rb:364:in `options_from_collection_for_select'
15:00:09 web.1   |   actionpack (3.2.14) lib/action_view/helpers/form_options_helper.rb:600:in `to_collection_select_tag'
15:00:09 web.1   |   actionpack (3.2.14) lib/action_view/helpers/form_options_helper.rb:191:in `collection_select'
15:00:09 web.1   |   actionpack (3.2.14) lib/action_view/helpers/form_options_helper.rb:646:in `collection_select'
15:00:09 web.1   |   client_side_validations (3.2.6) lib/client_side_validations/action_view/form_builder.rb:77:in `collection
_select_with_client_side_validations'
15:00:09 web.1   |   app/views/benefits/_form.html.haml:10:in `block in _app_views_benefits__form_html_haml___5210787370672092
58_70323180464100'
15:00:09 web.1   |   haml (4.1.0.beta.1) lib/haml/helpers/action_view_mods.rb:132:in `block (2 levels) in form_for_with_haml'
15:00:09 web.1   |   haml (4.1.0.beta.1) lib/haml/helpers.rb:284:in `with_tabs'
15:00:09 web.1   |   haml (4.1.0.beta.1) lib/haml/helpers/action_view_mods.rb:132:in `block in form_for_with_haml'
15:00:09 web.1   |   actionpack (3.2.14) lib/action_view/helpers/capture_helper.rb:40:in `block in capture'
15:00:09 web.1   |   actionpack (3.2.14) lib/action_view/helpers/capture_helper.rb:187:in `with_output_buffer'
...

1 个答案:

答案 0 :(得分:6)

堆栈跟踪告诉您需要知道的一切来解决这个问题。让我们学习捕鱼!

首先,“Y的未定义方法X”表示“您试图在对象X上调用方法Y,但Y没有该方法”。在这种情况下,您尝试在nil上调用map,而nil不会实现map。所以我们正在寻找一个我们称之为map的地方,然后我们将尝试找出为什么我们称之为map的对象可能为零。

  

15:00:09 web.1 | app / views / benefits / _form.html.haml:10:在_ block_views_benefits__form_html_haml ___ 5210787370672092的块中

这告诉你要查看_form.html.haml中的第10行。这就是你要解决这个问题的地方。但是,问题发生在lib/action_view/helpers/form_options_helper.rb:364方法的options_from_collection_for_select中。这是一个非常好的猜测,这对应于这一行:

  

= f.collection_select:benefit_type,@ lookup_tables1,:id,:title,:prompt =&gt;真

如果你看一下那里的来源,你可以看到它在呼唤什么。从堆栈跟踪顶部向后工作:

我们可以看到它在传入的map上调用collection。通过跟踪堆栈跟踪回到FormBuilder#collection_select方法,我们可以确切地确定这是哪个参数 - @lookup_tables1,在您的情况下。

现在,您在@lookup_tables1操作中设置了new,但在您createrender action: :new行动中未设置save。由此,我们可以推测,当您第一次尝试保存您的Benefit记录时,new会失败并返回false。您的第二个分支在那里运行,尝试渲染@lookup_tables1模板,但由于您没有设置collection_select@lookup_tables1失败,因为它试图从零创建一个选择框集合。

所以,你有两个任务:

  1. 在致电create
  2. 之前,使用render action: :new方法填充{{1}}
  3. 找出您的福利记录未能保存并修复的原因。
  4. 顺便说一句,您应该将Rails更新为最新的3.x系列(截至目前为3.2.19)。 3.2.14有几个漏洞已经修复过。