开发者

Rails 3: How to create a new nested resource?

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜