Rails [已解决] 关于嵌套表单

classicalliu · 2016年05月07日 · 最后由 classicalliu 回复于 2016年05月08日 · 3288 次阅读

要写关于嵌套表单的内容,然后我新开了一个项目测试嵌套表单…… 弄了一天也没弄成,所以来求助了 (┬_┬)

就是一对多的关系,在 1 方的表单内嵌套多方的表单😢 网上的资料都不太对或者不太全 看的似懂非懂怎么写都有点错

注释的部分是不知道要不要的,有说要写的有说內建的

class User < ActiveRecord::Base
  has_many :books
  accepts_nested_attributes_for :books

  # def books
  #   [@book1, @book2]
  # end

  # def books_attributes=(book_attributes)
  #   # book_attributes.each do |attributes|
  #   #   books.build(attributes)
  #   # end
  # end
end
class Book < ActiveRecord::Base
  belongs_to :user
end

User 只有一个 username 的属性,book 只有一个 name 的属性

然后 erb 文件是这么写的

<h1>User new</h1>

<%= form_for @user do |f| %>
    <%= f.label :username %>
    <%= f.text_field :username %>

    <% for book in @user.books %>
        <%= f.fields_for :books_attributes, book do |ff| %>
            <%= ff.label :name %>
            <%= ff.text_field :name %>
        <% end %>
    <% end %>

    <%= f.submit '提交' %>
<% end %>

最后是 UserController

class UsersController < ApplicationController
  def new
    @user = User.new
    2.times {@user.books.build}
  end

  def create
    @user = User.new(user_params)
    @user.save
    redirect_to root_url
  end

  private

  def user_params
    params.require(:user).permit(:username, books_attributes: [:name])
    # params.require(:user).permit!
  end

end

然后出的错误是这样的

求指导,感激不尽😘

折磨我一天各种尝试的问题解决辣<( ̄▽ ̄)> 在@watraludru 的提醒下修改成数组参数

所以最后是这么改的

<% for book in @user.books %>
    <%= f.fields_for 'books_attributes[]', book do |ff| %>
        <%= ff.label :name %>
        <%= ff.text_field :name %>
    <% end %>
<% end %>

其实一开始试过这种方案但是可能其它地方有错所以也没成功 而且查看 html 源码的时候有空的 [] 有点奇怪就又改掉了

user[books_attributes][][name]
<form class="new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><input type="hidden" name="authenticity_token" value="TqZUuCNqr06D36t7venGAdRWkpbT4ItUUOixcSWvBqudKbiy5aNB6S184eeODUs7m1yr55PWuuAFCK7GqGMN9A==" />
    <label for="user_username">Username</label>
    <input type="text" name="user[username]" id="user_username" />


            <label for="user_books_attributes__name">Name</label>
            <input type="text" name="user[books_attributes][][name]" id="user_books_attributes__name" />

            <label for="user_books_attributes__name">Name</label>
            <input type="text" name="user[books_attributes][][name]" id="user_books_attributes__name" />

    <input type="submit" name="commit" value="提交" />
</form>

官方文档 ---->>

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

从请求看,你的表单数据明显不对,books_attributes 应该对应的是个数组,而不是哈希,而且 permit 好像用錯喽。。。

#1 楼 @watraludru https://ruby-china.org/topics/24418 因为这个帖子的参数是这么写的(:з」∠) 而且你给的这两个 api 的参考资料都没讲要怎么写,只讲了传过来的参数长什么样子...并没有解决问题啊(:з」∠)

#2 楼 @classicalliu

  1. 用 rails console 进控制台,手工测试下确认需要对 model 传入怎样的参数再说吧,应该是数组,而不是哈希,因为你是一对多的关系,而不是一对一的关系
  2. 确定后,打印下 user_params 的结果看下,到底满不满足,应该有误,然后慢慢去改表单吧

#3 楼 @watraludru 好的,我先回寝室洗个澡冷静下就看看🌝

#3 楼 @watraludru lalala 我解决了,的确是数组的问题,问题出在 erb 上 整理下解决方案发出来🙄晕死了弄了一天到现在才弄出来 谢喽~

fields_for 不用 books_attributes,直接 fields_for :books。控制器 new 一个的时候,User.new(books: Book.new),你可以看你页面生成的表单元素。

#6 楼 @1208175976 我照着你说的试了下

<% for book in @user.books %>
    <%= f.fields_for :books, book do |ff| %>
        <%= ff.label :name %>
        <%= ff.text_field :name %>
    <% end %>
<% end %>
def new
  @user = User.new(books: Book.new)
end

会报错诶😳 也可能我没有理解你的意思……(:з」∠)

#7 楼 @classicalliu 恩,是我搞错了。不好意思喔。

has_one 的情况 nested_attributes 的 value 是一个 hash。has_many 的情况 nested_attributes 的 value 是一个 array。array 里的元素才是 hash。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号