partial form for nested models in rails 3

2019-08-03 15:58发布

问题:

I have two models pages and author, here is the code of model pages:

edit -1

now my models are as follows:

class Page < ActiveRecord::Base
validates :title, :presence => true

belongs_to :author


end

author model:

class Author < ActiveRecord::Base

has_many :pages
end

and my form is as follows:

 <%= form_for(@page) do |f| %>
  <% if @page.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@page.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @page.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
   <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
   <p>
   <%= f.fields_for :author do |fields| %>
         <%= f.label :author %><br />
         <%= fields.text_field :author %>
   <% end %>
   </p>
   <p>
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </p>
   <p>
    <%= f.label :reference %><br />
    <%= f.select(:reference,[['google',1],['yahoo',2],['MSN',3],['Ask',4]]) %>
  </p>
   <%= f.submit "Submit" %>
<% end %>

and controller :

class PagesController < ApplicationController

  def index
    @total = Page.count
    @pages = Page.find(:all)
  end

  def show
    @page = Page.find(params[:id])
  end

  def new
    @page = Page.new


  end

  def create
    @page = Page.new(params[:page])
    if @page.save
        redirect_to pages_path, :notice => "The data has been saved!"
    else
        render "new"
    end
  end 

  def edit
    @page = Page.find(params[:id])


  end

  def update
    @page = Page.find(params[:id])

        if @page.update_attributes(params[:page])
            redirect_to pages_path, :notice => "Your post has been updated!"
        else
            render "edit"
        end 

  end 

  def destroy
    @page = Page.find(params[:id])
    @page.destroy
    redirect_to pages_path, :notice => "Your page has been deleted!"
  end
end

Now when i am submitting the form it is giving me this error:

ActiveRecord::AssociationTypeMismatch in PagesController#create

Author(#40328004) expected, got ActiveSupport::HashWithIndifferentAccess(#32291496)
Rails.root: C:/rorapp

Application Trace | Framework Trace | Full Trace
app/controllers/pages_controller.rb:19:in `new'
app/controllers/pages_controller.rb:19:in `create'
Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"hzBlXsdUjEDDCLp036R8bJBwep6BdATSvJPNwt0M8Dg=",
 "page"=>{"title"=>"",
 "body"=>"",
 "author"=>{"author"=>""},
 "email"=>"",
 "reference"=>"1"},
 "commit"=>"Submit"}
Show session dump

Show env dump

Response

Headers:

None

and one more problem if I add accepts_nested_attributes_for :author to my Page model, then the field is not displayed at all. I really want to accomplish this.. any help?

回答1:

Apparently this doesn't work in reverse with the association. I'm sorry for the mistake. You could do the following, but then your pages controller is acting on the author, which isn't really appropriate. You could make an author controller though, and include fields_for :pages, to have the author and the first page created at the same time.

class PagesController < ApplicationController
  def new
    @author = Author.new
    @page = @author.pages.new
  end


  def create
    @author = Author.create(params[:author])
  end
end

class Author < ActiveRecord::Base
  has_many :pages
  accepts_nested_attributes_for :pages
end

class Page < ActiveRecord::Base
  belongs_to :author
end

<%= form_for(@author, :url => pages_url) do |f| %>
    <%= f.text_field :author %>
    <%= f.fields_for :pages do |fields| %>
        <%= fields.text_area :body %>
    <% end %>
<% end %>