【问题标题】:Nested model/form doesn't create an entry嵌套模型/表单不创建条目
【发布时间】:2025-11-28 21:40:02
【问题描述】:

在研究 ruby​​ 的嵌套模型时,我遇到了一个问题。

考虑以下场景,

我有以下型号:

  • 作者
  • 书籍

具有以下规格:

作者:

class Author < ActiveRecord::Base
  attr_accessible :name
  has_many :books, dependent: :destroy

  accepts_nested_attributes_for :books #I read this is necessary here: http://*.com/questions/12300619/models-and-nested-forms

  # and some validations...
end

书:

class Book < ActiveRecord::Base
  attr_accessible :author_id, :name, :year
  belongs_to :author

  #and some more validations...
end

我想为作者添加一本书。这是我的 authors_controller:

def new_book
  @author = Author.find(params[:id])
end

def create_book
  @author = Author.find(params[:id])
  if @author.books.create(params[:book]).save
    redirect_to action: :show
  else
    render :new_book
  end
end

这是我尝试使用的表单:

<h1>Add new book to <%= @author.name %>'s collection</h1>
<%= form_for @author, html: { class: "well" } do |f| %>
    <%= fields_for :books do |b| %>
        <%= b.label :name %>
        <%= b.text_field :name %>
        <br/>
        <%= b.label :year %>
        <%= b.number_field :year %>
    <% end %>
    <br/>
    <%= f.submit "Submit", class: "btn btn-primary" %>
    <%= f.button "Reset", type: :reset, class: "btn btn-danger" %>
<% end %>

问题: 当我输入数据并单击“提交”时,它甚至会将我重定向到正确的作者,但它不会为该作者保存新记录。 经过大量研究,我似乎无法在这里找到我做错了什么。

【问题讨论】:

    标签: ruby-on-rails ruby rails-activerecord nested-forms


    【解决方案1】:

    将 authors_controller 更改为:

    def new_book
      @author = Author.find(params[:id])
      @book = Book.new
    end
    

    您的表格:

    <h1>Add new book to <%= @author.name %>'s collection</h1>
    <%= form_for ([@author, @book]), html: { class: "well" } do |f| %>
    

    还有,routes.rb

    resources :authors do
      resources :books
    end  
    

    【讨论】:

    • 显然这改变了我的路由机制...它现在给了我undefined method `author_books_path' 并引用了表单的第二行...
    • 请参考blog.dominicsayers.com/2011/08/24/…从零开始实现子表单。
    【解决方案2】:

    你错过了一些东西。

    控制器:

    ...
    def new_book
      @author = Author.find(params[:id])
      @author.books.build
    end
    ...
    

    看,是f.fields_for 而不仅仅是fields_for

    <%= f.fields_for :books do |b| %>
      <%= b.label :name %>
      <%= b.text_field :name %>
      <br/>
      <%= b.label :year %>
      <%= b.number_field :year %>
    <% end %>
    

    【讨论】:

    • 看起来已经好多了,但现在它要求我在 books 控制器中创建一个方法 - 知道为什么吗?
    【解决方案3】:

    您还需要在您的作者模型可访问方法上添加:nested_attributes_for_books。 Author 控制器上的 create 方法不需要添加任何代码。

    注意:您将 Books 控制器设置为在成功时呈现“books#show”。如果应用程序将您重定向到作者,则意味着 作者控制器 正在处理图书的创建,除非您将其设置为重定向到作者而不是图书。

    【讨论】: