简体   繁体   中英

How do I render a partial containing a form_for for an edit function?

I have a div in a parent view that renders a show partial. In this show partial, I have a button that should change the parent's partial to render the 'form' partial to edit the object, but I keep getting jammed up because it seems that the 'form' partial's form_for is missing the @project object.

How can I pass this object to the 'form' partial? Am I missing something else?

I am rather new to using AJAX. Happy to provide more information if you need.

The error I am getting in the server terminal is

ActionView::Template::Error (First argument in form cannot contain nil or be empty):

routes.rb

    get 'switchProjectView', to: 'projects#switch_main_view'
    resources :projects

projects_controller.rb

class ProjectsController < ApplicationController

  def new
    @project = Project.new
  end

  def create
    @project = Project.new(project_params)
    if @project.save
      flash[:success] = "New Project Added"
      redirect_to @project 
    else
      flash[:danger] = "Project Not Added. Please Try Again"
    end

  end

  def show
    @project = Project.find(params[:id])
  end

  def index
    @projects = Project.all
  end

  def update 
    @project = Project.find(params[:id])
    if @project.update_attributes(project_params)
      redirect_to @project
    else
      render 'edit'
    end
  end

  def edit

  end

  def switch_main_view
    respond_to do |format|               
      format.html
      format.js
    end    
  end     


  def project_params
    params.require(:project).permit(:main_contact_name, :id, :main_contact_phone, :main_contact_email, :project_name)
  end

end

show.html.erb

    <div class="body">
      <div class="center jumbotron heading-jumbo">
        <h1><%= @project.project_name %></h1>  
      </div>

      <div class="body-jumbo jumbotron" id='project-details'>
        <%= render "projects/show" %>
      </div>
    </div>

switch_main_view.js.erb

    $('#project-details').html("<%= j render :partial => 'projects/form' %>");

_form.html.erb

  <%= form_for(@project) do |f| %>

      <%= f.label :project_name %>
      <%= f.text_field :project_name, class: 'form-control'%>

      <%= f.label :main_contact_name %>
      <%= f.text_field :main_contact_name, class: 'form-control'%>

      <%= f.label :main_contact_phone %>
      <%= f.text_field :main_contact_phone, class: 'form-control'%>

      <%= f.label :main_contact_email %>
      <%= f.text_field :main_contact_email, class: 'form-control'%>

      <%= f.submit 'Save Project', class: 'btn btn-primary'%>

  <% end %>

_show.html.erb

<div class='text-center center'>
    <h3><strong>Project Information</strong></h2>  
</div>
<h2>Start Date: Launch Date:</h1>
<span class='pull-right jumbo-btn-span'><%= link_to "Edit Project Information", switchProjectView_path(@project), remote: true, class:'btn btn-primary jumbo-btn' %></span>
<h2>Primary Conact's Name:  <%= @project.main_contact_name %></h2>
<h2>Primary Conact's Phone: <%= @project.main_contact_phone %></h2>
<h2>Primary Conact's Email: <%= @project.main_contact_email %></h2>

Well, with each request, you need to re-initialize the variable in your controller method. In your case, you need to do the following:

def switch_main_view
  @project = Project.new
  respond_to do |format|               
    format.html
    format.js
  end    
end

Doing so will enable you to get rid of the error: First argument in form cannot contain nil or be empty , but that won't enable you to do what you are actually trying to do.

When you use link_to , by default it goes for an HTML request as you can see in Rails logs, something like following will appear:

Processing by ProjectsController#switch_main_view as HTML

In order to get the JS response, you need to tell link_to that you are up for a JS response, not for an HTML response, and you can do by passing format: :js in link_to like:

<%= link_to "Edit Project Information", switchProjectView_path(@project, format: :js), remote: true, class:'btn btn-primary jumbo-btn' %></span>

remote: true will be there to make sure that you aren't reloading the contents of the page, rather you are trying to fetch something from the server in the background.

Your request "switchProjectView_path(@project)" only send object id to server, so you need to load the object to present it in view for response.
1. First the route should look like this so that, the url could contain object id:
get 'switchProjectView/:id', to: 'projects#switch_main_view', as:"switchProjectView"
2. You have to load the object in controller: def switch_main_view @project = Project.find(params[:id]) respond_to do |format| format.html format.js end end def switch_main_view @project = Project.find(params[:id]) respond_to do |format| format.html format.js end end

尝试在调用局部变量时传递变量:

$('#project-details').html("<%= j render :partial => 'projects/form', locals: {project: @project} %>");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM