编辑/更新嵌套模型(update_attributes错误)

时间:2013-01-11 06:04:24

标签: ruby-on-rails ruby-on-rails-3.2

在Rails 3.2中提交具有嵌套模型的更新表单时出现以下错误。任何有关这方面的帮助将不胜感激。

NoMethodError in ProfilesController#update

undefined method `update_attributes' for nil:NilClass
Rails.root: C:/Documents and Settings/Workspace/project_x

Application Trace | Framework Trace | Full Trace
app/controllers/profiles_controller.rb:32:in `update'
Request

Parameters:

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"PQFLzhgvFzRyJ2BT/GdIpjRiOM729JoYQUHrZGUi08c=",
 "profile"=>{"addresses_attributes"=>{"0"=>{"address1"=>"588 brodie",
 "address2"=>"Apt1115",
 "city"=>"Austin",
 "state"=>"Alabama",
 "zip"=>"78745",
 "id"=>"1"}},
 "vital_attributes"=>{"birthday(2i)"=>"1",
 "birthday(3i)"=>"11",
 "birthday(1i)"=>"1910",
 "height_feet"=>"3",
 "height_inches"=>"3",
 "weight"=>"220",
 "id"=>"1"},
 "certificate_attributes"=>{"C_ASEL"=>"1",
 "C_AMEL"=>"1",
 "C_ASES"=>"1",
 "C_AMES"=>"0",
 "ATP_ASEL"=>"0",
 "ATP_AMEL"=>"0",
 "ATP_ASES"=>"0",
 "ATP_AMES"=>"0",
 "FI_ASE"=>"1",
 "FI_AME"=>"1",
 "FI_INSTA"=>"1",
 "GI_Basic"=>"0",
 "GI_Advanced"=>"0",
 "GI_Instrument"=>"0",
 "id"=>"1"}},
 "commit"=>"Save & Continue",
 "id"=>"1"}

以下是涉及的模型,控制器和表单:

class Profile < ActiveRecord::Base
   attr_accessible :addresses_attributes, :vital_attributes, :certificate_attributes

   belongs_to :contact
   has_many :addresses
   has_one :certificate
   has_one :vital

   accepts_nested_attributes_for :addresses, :certificate, :vital
end

class Address < ActiveRecord::Base
   belongs_to :profile
end

class Vital < ActiveRecord::Base
   belongs_to :profile
end

class Certificate < ActiveRecord::Base  
   belongs_to :profile  
end


class ProfilesController < ApplicationController

   before_filter :authenticate, :only => [:show, :edit, :update]
   before_filter :correct_contact, :only => [:show, :edit, :update]
.
.
.

def edit
   @profile = Profile.find(params[:id])
   @address = @profile.addresses.first
   @vital = @profile.vital
   @certificate = @profile.certificate
end

def update
   if @profile.update_attributes(params[:profile])
      flash[:success] = "Profile updated"
      render 'edit'
   else
      render 'edit'
   end
end 


private #######################################################################

def authenticate
   deny_access unless signed_in?
end

def correct_contact
   @contact = Contact.find(params[:id])
   redirect_to(root_path) unless current_contact?(@contact)
end

end


<%= form_for @profile, :html => { :class => "form-horizontal" } do |f| %>

<%= f.fields_for :addresses do |aa| %> 
   <%= aa.label :address1, "Address 1:", :class => "control-label" %>
   <%=aa.label :address2, "Address 2:", :class => "control-label" %>
   <%=aa.text_field :address2 %>
   <%= aa.label :city, "City:", :class => "control-label" %>
   <%= aa.text_field :city %>
   <%= aa.label :state, "State:", :class => "control-label" %>
   <%= aa.select(:state, options_for_select([["Alabama", "Alabama"], ["Texas", "Texas"]]), {}, :class => "select-auto-size") %>
   <%= aa.label :zip, "Zip Code:", :class => "control-label" %>
   <%= aa.text_field :zip %>                        
<% end %>                           

<%= f.fields_for :vital do |ab| %>
   <%= ab.label :birthday, "Birthday:", :class => "control-label" %>
   <%= ab.date_select :birthday, { :start_year => 1910, :end_year => 1995, :order => [:month, :day, :year] },{ :class => "select-auto-size" } %>
   <%= ab.label :sex, "Sex:", :class => "control-label" %>
   <%= ab.radio_button :sex, "Male", :id => "optionRadios1" %> Male&nbsp;&nbsp;
   <%= ab.radio_button :sex, "Female", :id => "optionRadios2" %> Female
   <%= ab.label :height, "Height:", :class => "control-label" %>
   <%= ab.select(:height_feet, options_for_select([["3'", 3], ["4'", 4]]), {}, :class => "select-auto-size") %>
   <%= ab.select(:height_inches, options_for_select([["3''", 3], ["4''", 4]]), {}, :class => "select-auto-size") %>
   <%= ab.label :weight, "Weight:", :class => "control-label" %>
   <%= ab.text_field :weight, :class => "input-mini" %><span>
   <% end %>                                

<%= f.fields_for :certificate do |ac| %>
   <label class="checkbox"><%= ac.check_box :C_ASEL %> Single</label>
   <label class="checkbox"><%= ac.check_box :C_AMEL %> Multi</label>
   <label class="checkbox"><%= ac.check_box :C_ASES %> Other</label>
<% end %>

<%= f.submit "Save & Continue", :class => "btn" %>

<% end %>

1 个答案:

答案 0 :(得分:3)

  

nil的未定义方法`update_attributes':NilClass

这告诉您,在update中的ProfilesController控制器操作中,您正在调用update_attributes当前nil的变量而不是模型的实例我正在尝试更新。具体地

def update
  if @profile.update_attributes(params[:profile])
    # ...

您没有将@profile分配给任何模型实例,因此它是nil。您必须执行edit行动中的操作。

def update
  @profile = Profile.find(params[:id])
  if @profile.update_attributes(params[:profile])
    # ...