Rails更新表单抛出"未定义的方法`[]'为零:NilClass"

时间:2016-08-25 08:48:51

标签: ruby-on-rails

我试图在Rails上创建一个更新表单,对于一个对另一个有外键的对象。但是,它会抛出此错误。我还是非常认真地使用Ruby on Rails并且刚刚关注了视频教程,所以我不太清楚如何解释这个。我目前正在使用rails 5.0.0

travelers_controllers.rb下面的行

@prf = update_prof_params["profiles_attributes"]["0"]

抛出错误

  

未定义的方法`[]'为零:NilClass

edit.html.erb

<div class="col-md-7 col-md-offset-3 main">
  <% provide(:title, "Edit user")%>
  <center><h1>Update your profile</h1></center>
  <%= form_for(@person) do |f| %>
    <%= render 'shared/error_messages' %>
    <div class="col-md-12">
      <%= render 'layouts/profilefields', f: f %>
      <%= f.submit "Save Changes", class: "btn btn-large btn-primary" %>
    </div>
  <% end %>
</div>

_profilefields.html.erb

<%= f.fields_for :profiles do |prf|%>
  <!--
  <% if !@profileInfo["avatar"].blank? %>
    <%= image_tag @contactInfo.avatar_url(:medium).to_s, :class=>"profilePhoto" %>
  <% end %>
  <div class="photoPreview">
    <i class="fa fa-upload photoUpload"></i>
    <p id="uploadClick">Click to Upload</p>
  </div>

  <%= prf.file_field :avatar, accept: 'image/png,image/gif,image/jpeg, image/jpg', id: 'uploadAvatar' %>
  <p class="deletePhoto">Delete</p>
  -->

  <%= prf.label :about %>
  <%= prf.text_field :about, :class => "form-control" %>
  <%= prf.label :why %>
  <%= prf.text_field :why, :class => "form-control" %>
  <%= prf.label :goals %>
  <%= prf.text_field :goals, :class => "form-control" %>


  <%= prf.hidden_field :traveler_id, value: current_traveler.id %>
<% end %>

travelers_controller.rb

class TravelersController < ApplicationController
  def edit
    @person = Traveler.find(params[:id])
    @profileInfo = Profile.find_or_initialize_by(traveler_id: params[:id])
    #@profileInfo[:email] = current_traveler.email

    #This builds the form
    @person.build_profile(@profileInfo.attributes)
  end

  def show
  end

  def update
    @prf = update_prof_params["profiles_attributes"]["0"]
    @prof = Profile.find_or_create_by(traveler_id: current_traveler.id)
    if @prof.update_attributes(prf) 
        flash[:success] = "Profile updated"
        redirect_to feed_path
      else # Failed. Re-render the page as unsucessful
        render :edit
    end
  end

  private 
    def update_prof_params
      params.require(:traveler).permit(profiles_attributes: [:about, :why, :goals,
          :traveler_id])
    end
end

模型

class Profile < ApplicationRecord
    belongs_to :traveler, foreign_key: "traveler_id"
end

class Traveler < ApplicationRecord
  # Include default devise modules. Others available are:
  # , :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :trackable, :validatable

  has_one :profile
end

1 个答案:

答案 0 :(得分:1)

在TravelersController中,方法update应该用于更新旅行者,而不是配置文件,因此您可以通过嵌套属性使用批量更新,如下所示:

def update
  @traveler = Traveler.find(params[:id])
  if @traveler.update(update_prof_params) 
    flash[:success] = "Profile updated"
    redirect_to feed_path
  else # Failed. Re-render the page as unsucessful
    render :edit
  end
end

因此,上面允许您创建/更新属于旅行者的个人资料。此外,确保在模型中定义了嵌套属性:

<强> traveler.rb

class Traveler < ActiveRecord::Base
  # Your code here
  #....

  # Make sure define this
  accepts_nested_attributes_for :profile
end

更新:允许的参数应为:

def update_prof_params
  params.require(:traveler).permit(profile_attributes: [:about, :why, :goals, :traveler_id])
end

正如您所见profile_attributes应该使用而不是profiles_attributes,因为traveler只有一个profile