2010-09-24 121 views
63

該部分的Getting Started Rails Guide種光澤,因爲它沒有實現評論控制器的「新」動作。在我的應用程序,我有了許多章節書型號:Rails 3:如何創建一個新的嵌套資源?

class Book < ActiveRecord::Base 
    has_many :chapters 
end 

class Chapter < ActiveRecord::Base 
    belongs_to :book 
end 

在我的路線文件:

resources :books do 
    resources :chapters 
end 

現在我想要實現的章節控制器的「新」行動:

class ChaptersController < ApplicationController 
    respond_to :html, :xml, :json 

    # /books/1/chapters/new 
    def new 
    @chapter = # this is where I'm stuck 
    respond_with(@chapter) 
    end 

這樣做的正確方法是什麼?另外,視圖腳本(表單)應該是什麼樣的?

回答

119

首先你必須在你的章節控制器中找到相應的書來爲他建立一章。你可以做你的行爲是這樣的:

class ChaptersController < ApplicationController 
    respond_to :html, :xml, :json 

    # /books/1/chapters/new 
    def new 
    @book = Book.find(params[:book_id]) 
    @chapter = @book.chapters.build 
    respond_with(@chapter) 
    end 

    def create 
    @book = Book.find(params[:book_id]) 
    @chapter = @book.chapters.build(params[:chapter]) 
    if @chapter.save 
    ... 
    end 
    end 
end 

在您的形式,new.html.erb

form_for(@chapter, :url=>book_chapters_path(@book)) do 
    .....rest is the same... 

,或者你可以嘗試速記

form_for([@book,@chapter]) do 
    ...same... 

希望這有助於。

+4

爲了重構代碼 - 也可以使用get_book方法來查找book @book = Book.find(params [:book_id]),然後將此方法用作before過濾器。這是因爲你在章節控制器中實現的任何方法都需要它所屬的書籍對象。 – Ninad 2011-10-11 08:47:19

+0

Re:上面的評論,如果你有多本書的孩子,你可以將'get_book'方法重構爲'BookHelper'和'include BookHelper'到你的書籍控制器和書籍相關的控制器中。 – ocodo 2013-02-22 23:28:47

+0

這不會創建一個額外的選擇查詢數據庫? – 2015-12-28 17:12:51

6

嘗試@chapter = @book.build_chapter。當你致電@book.chapter,它是零。你不能這樣做nil.new

編輯:我剛剛意識到那本書最有可能has_many章節......上面是has_one。您應該使用@chapter = @book.chapters.build。章節「空數組」實際上是一個特殊的對象,它響應build添加新的關聯。

1

也許不相干,但是從這個問題的標題你可能會到達這裏尋找如何做一些稍微不同的事情。

比方說,你想要做Book.new(name: 'FooBar', author: 'SO'),你想一些元數據拆分成一個獨立的模型,叫做readable_config這是多態和商店nameauthor多個型號。

你如何接受Book.new(name: 'FooBar', author: 'SO')建立Book模型,也是readable_config模型(我會,也許錯了,叫「嵌套資源」)

這可以爲這樣做:

class Book < ActiveRecord::Base 
    has_one :readable_config, dependent: :destroy, autosave: true, validate: true 
    delegate: :name, :name=, :author, :author=, :to => :readable_config 

    def readable_config 
    super ? super : build_readable_config 
    end 
end 
+0

非常了不起,我喜歡這個解決方案,謝謝! – sidney 2016-06-27 06:59:08