2015-11-05 22 views
0

尝试创建新的嵌套表单时遇到错误。嵌套表单属性时出现“构建”错误

我有3种型号:

class Child < ActiveRecord::Base 
has_many :hires 
has_many :books, through: :hires 
end 

class Hire < ActiveRecord::Base 
belongs_to :books 
belongs_to :children 
accepts_nested_attributes_for :books 
accepts_nested_attributes_for :children 
end 

class Book < ActiveRecord::Base 
    has_many :hires 
    has_many :children, through: :hires 
    belongs_to :genres 
end 

我试图建立一个视图让孩子从“聘请”两本书。

的看法是这样的:

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

<%= hires_form.label :child %><br> 
<%= hires_form.select(:child, Child.all.collect {|a| [a.nickname, a.id]}) -%> 

    <%= f.fields_for :books do |books_form| %> 

    <%= books_form.label :book %><br> 
    <%= books_form.select(:book, Book.all.collect {|a| [a.Title, a.id]}) -%> 
    <%= books_form.label :book %><br> 
    <%= books_form.select(:book, Book.all.collect {|a| [a.Title, a.id]}) -%> 
    <% end %> 

<%= f.submit %> 
<% end %> 

控制器看起来是这样的:

class HiresController < ApplicationController 

...  

def new 
    @hire = Hire.new 
    2.times { @hire.books.build } 
end 

def create 
    @hire = Hire.new(hire_params) 

    respond_to do |format| 
     if @hire.save 
     format.html { redirect_to @hire, notice: 'Hire was successfully created.' } 
     format.json { render :show, status: :created, location: @hire } 
     else 
     format.html { render :new } 
     format.json { render json: @hire.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

...  

private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_hire 
     @hire = Hire.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def hire_params 
     params.require(:hire).permit(:book, :child, books_attributes: [:id, :book, :child, :_destroy]) 
    end 
end 

,我发现了错误:

undefined method `build' for nil:NilClass 

我觉得这是很明显的东西我失踪,但任何帮助将是伟大的!

回答

0
belongs_to :books 
belongs_to :children 

您需要单数化这些。

belongs_to :book 
belongs_to :child 

也看到铁轨指南第2.4节作为参考“的的has_many:通过协会”http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

请记住,您使用的租用对象的belongs_to的。

注意,使用的是belongs_to的关联时添加的方法:

association(force_reload = false) 
association=(associate) 
build_association(attributes = {}) 
create_association(attributes = {}) 
create_association!(attributes = {}) 

所以,你应该能够使用的方法build_book录用对象(如@的hire.build_book @ hire.build_child )。

由协会的has_many添加的方法是:

collection(force_reload = false) 
collection<<(object, ...) 
collection.delete(object, ...) 
collection.destroy(object, ...) 
collection=(objects) 
collection_singular_ids 
collection_singular_ids=(ids) 
collection.clear 
collection.empty? 
collection.size 
collection.find(...) 
collection.where(...) 
collection.exists?(...) 
collection.build(attributes = {}, ...) 
collection.create(attributes = {}) 
collection.create!(attributes = {}) 

它可以在你的书和子对象使用。例如:@book.childeren.build or @child.books.build.

更多信息参见轨道引导部分4.2和4.3 '通过添加的方法..': http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

+0

嗯...感谢。做出这样的改变:'belongs_to:book belongs_to:child'并且保持控制器代码为'2.times {@ hire.books.build}'仍然出现错误'undefined method'book'for#'' 。当我将控制器代码更改为'2.times {@ hire.book.build}'时,我得到'nil:NilClass'的未定义方法'build'的错误。有什么想法吗? –

+0

是的,但是Hire会只有一个Book和一个Child对象。如果你想访问书籍,你需要从一个子对象'@ child.books.build'来完成。如果您需要从Hire对象执行此操作,请使用'@ hire.build_book'。 仅供参考,请参阅导轨指南子部分'4.1.1由belongs_to添加的方法'。 –