The Getting Started Rails Guide kind of glosses over this part since it doesn't implement the "new" action of the Comments controller. In my application, I have a book model that has many chapters:
class Book < ActiveRecord::Base
has_many :chapters
end
class Chapter < ActiveRecord::Base
belongs_to :book
end
In my routes file:
resources :books do
resources :chapters
end
Now I want to implement the "new" action of th开发者_如何学JAVAe Chapters controller:
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
What is the right way to do this? Also, What should the view script (form) look like?
First you have to find the respective book in your chapters controller to build a chapter for him. You can do your actions like this:
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
In your form, new.html.erb
form_for(@chapter, :url=>book_chapters_path(@book)) do
.....rest is the same...
or you can try a shorthand
form_for([@book,@chapter]) do
...same...
Try @chapter = @book.build_chapter
. When you call @book.chapter
, it's nil. You can't do nil.new
.
EDIT: I just realized that book most likely has_many chapters... the above is for has_one. You should use @chapter = @book.chapters.build
. The chapters "empty array" is actually a special object that responds to build
for adding new associations.
Perhaps unrelated, but from this question's title you might arrive here looking for how to do something slightly different.
Lets say you want to do Book.new(name: 'FooBar', author: 'SO')
and you want to split some metadata into a separate model, called readable_config
which is polymorphic and stores name
and author
for multiple models.
How do you accept Book.new(name: 'FooBar', author: 'SO')
to build the Book
model and also the readable_config
model (which I would, perhaps mistakenly, call a 'nested resource')
This can be done as so:
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
精彩评论