【问题标题】:Rails 3: How to create a new nested resource?Rails 3:如何创建新的嵌套资源?
【发布时间】:2011-04-16 14:22:21
【问题描述】:

Getting Started Rails Guide 类型掩盖了这部分,因为它没有实现 Comments 控制器的“新”操作。在我的应用程序中,我有一个包含许多章节的书籍模型:

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

这样做的正确方法是什么?还有,视图脚本(表单)应该是什么样子的?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3


    【解决方案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...     
    

    【讨论】:

    • 为了重构代码 - 也可以使用 get_book 方法找到 book @book = Book.find(params[:book_id]) ,然后将此方法用作前置过滤器。这是因为你在章节控制器中实现的任何方法都需要它所属的 book 对象。
    • 回复:上面的评论,如果你有多个 book 的孩子,你会在你的 books 控制器和 book 相关的控制器中将 get_book 方法重构为 BookHelperinclude BookHelper。跨度>
    • 这不会为 db 创建额外的选择查询吗?
    • 你指的是什么@ArnoldRoa?
    【解决方案2】:

    试试@chapter = @book.build_chapter。当您致电@book.chapter 时,它是零。你不能这样做nil.new

    编辑:我刚刚意识到这本书很可能有_many 章......以上是has_one。你应该使用@chapter = @book.chapters.build。章节“空数组”实际上是一个特殊的对象,响应build添加新的关联。

    【讨论】:

      【解决方案3】:

      也许不相关,但从这个问题的标题来看,您可能会在这里寻找如何做一些稍微不同的事情。

      假设你想做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
      

      【讨论】:

        最近更新 更多