Rails 3: Как создать новый вложенный ресурс?
"Руководство по началу работы с Rails" , заглядывая в эту часть, поскольку оно не реализует "новое" действие контроллера комментариев. В моем приложении у меня есть модель книги, которая имеет много глав:
class Book < ActiveRecord::Base
has_many :chapters
end
class Chapter < ActiveRecord::Base
belongs_to :book
end
В файле маршрутов:
resources :books do
resources :chapters
end
Теперь я хочу реализовать "новое" действие контроллера Chapters:
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
Каков правильный способ сделать это? Кроме того, как выглядит вид script (форма)?
Ответы
Ответ 1
Сначала вы должны найти соответствующую книгу в своем главном контроллере, чтобы построить для него главу. Вы можете выполнять следующие действия:
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...
Надеюсь, что это поможет.
Ответ 2
Попробуйте @chapter = @book.build_chapter
. Когда вы вызываете @book.chapter
, оно равно нулю. Вы не можете сделать nil.new
.
EDIT: Я только понял, что книга, скорее всего, имеет несколько глав... выше для has_one. Вы должны использовать @chapter = @book.chapters.build
. Главы "пустой массив" на самом деле представляют собой специальный объект, который отвечает на build
для добавления новых ассоциаций.
Ответ 3
Возможно, несвязанный, но из этого вопроса вы можете приехать сюда, чтобы посмотреть, как сделать что-то немного другое.
Предположим, вы хотите сделать Book.new(name: 'FooBar', author: 'SO')
, и хотите разбить некоторые метаданные на отдельную модель, называемую readable_config
, которая является полиморфной и хранит name
и author
для нескольких моделей.
Как вы принимаете 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