rails 5 accepts_nested_attributes 不工作

rails 5 accepts_nested_attributes Not Working

我只是在试验 Rails 5,然后发现了 accepts_nested_attributes_for。但我无法让它工作。 我做错了什么

这是我的模型:

  1. Activity

这里是 SQL Table 定义

型号代码

class Person < ApplicationRecord
  has_many :activities
  accepts_nested_attributes_for :activities
end


class Activity < ApplicationRecord
  belongs_to :person
end

正在阅读 API 文档(accepts_nested_attributes_for

我创建了一个参数散列,并尝试将其提交给 Person Class。

params = {person: {name: 'Joe', activities_attributes: [{description: "Hiking"}]} }

当我尝试 运行 这个特定的代码时,而不是创建一个名为 "Joe" 的新个人记录,并在 "Hiking" 的活动下创建新的关联记录,它简单地失败了。

>> params = {person: {name: 'Joe', activities_attributes: [{description: "Hiking"}]} }
{:person=>{:name=>"Joe", :activities_attributes=>[{:description=>"Hiking"}]}}


>> Person.create(params[:person])
   (12.6ms)  BEGIN
   (0.6ms)  ROLLBACK
#<Person id: nil, name: "Joe", age: nil, adult: nil, created_at: nil, updated_at: nil>

但一步一步来似乎效果不错:

>> Person.create(:name => "Joe")
   (6.3ms)  BEGIN
  SQL (31.6ms)  INSERT INTO "people" ("name", "created_at", "updated_at") VALUES (, , ) RETURNING "id"  [["name", "Joe"], ["created_at", 2016-07-13 19:30:35 UTC], ["updated_at", 2016-07-13 19:30:35 UTC]]



>> a = Person.first
  Person Load (9.1ms)  SELECT  "people".* FROM "people" ORDER BY "people"."id" ASC LIMIT   [["LIMIT", 1]]
#<Person id: 35, name: "Joe", age: nil, adult: nil, created_at: "2016-07-13 19:30:35", updated_at: "2016-07-13 19:30:35">


>> a.activities_attributes = [{:name => "Hiking"}]
[{:name=>"Hiking"}]


>> a.save
   (0.2ms)  BEGIN
  Person Load (0.6ms)  SELECT  "people".* FROM "people" WHERE "people"."id" =  LIMIT   [["id", 35], ["LIMIT", 1]]
  SQL (13.0ms)  INSERT INTO "activities" ("person_id", "name", "created_at", "updated_at") VALUES (, , , ) RETURNING "id"  [["person_id", 35], ["name", "Hiking"], ["created_at", 2016-07-13 19:31:02 UTC], ["updated_at", 2016-07-13 19:31:02 UTC]]
   (6.8ms)  COMMIT
true


>> a
#<Person id: 35, name: "Joe", age: nil, adult: nil, created_at: "2016-07-13 19:30:35", updated_at: "2016-07-13 19:30:35">


>> a.activities
  Activity Load (12.4ms)  SELECT "activities".* FROM "activities" WHERE "activities"."person_id" =   [["person_id", 35]]
#<ActiveRecord::Associations::CollectionProxy [#<Activity id: 7, person_id: 35, name: "Hiking", created_at: "2016-07-13 19:31:02", updated_at: "2016-07-13 19:31:02", description: nil>]>

人Table

testing_development=# \d+ people;
                                                         Table "public.people"
   Column   |            Type             |                      Modifiers                      | Storage  | Stats target | Description 
------------+-----------------------------+-----------------------------------------------------+----------+--------------+-------------
 id         | integer                     | not null default nextval('people_id_seq'::regclass) | plain    |              | 
 name       | character varying           |                                                     | extended |              | 
 age        | integer                     |                                                     | plain    |              | 
 adult      | boolean                     |                                                     | plain    |              | 
 created_at | timestamp without time zone | not null                                            | plain    |              | 
 updated_at | timestamp without time zone | not null                                            | plain    |              | 
Indexes:
    "people_pkey" PRIMARY KEY, btree (id)

Activity Table

testing_development=# \d+ activities;
                                                          Table "public.activities"
   Column    |            Type             |                        Modifiers                        | Storage  | Stats target | Description 
-------------+-----------------------------+---------------------------------------------------------+----------+--------------+-------------
 id          | integer                     | not null default nextval('activities_id_seq'::regclass) | plain    |              | 
 person_id   | integer                     |                                                         | plain    |              | 
 name        | text                        |                                                         | extended |              | 
 created_at  | timestamp without time zone | not null                                                | plain    |              | 
 updated_at  | timestamp without time zone | not null                                                | plain    |              | 
 description | text                        |                                                         | extended |              | 
Indexes:
    "activities_pkey" PRIMARY KEY, btree (id)
    "index_activities_on_person_id" btree (person_id)

我让它工作了,但不确定这是 Rails 5 的错误,还是只是改变了事情的完成方式。

我如何让它工作的是看看这个问题是否与 rails 5. 我创建了一个 Rails 4.2 应用程序,具有相同的代码,并且 有效.

它开始工作后,我查看了在线帖子,看看是否能找到 rails 中发生这种情况的原因。这些是对我有帮助的资源:

Trouble with accepts_nested_attributes_for in Rails 5.0.0.beta3, -api option

class Post < ApplicationRecord
  belongs_to :member, optional: true
end

我添加了那行,效果非常好。

>> params = {person: {name: "Testing", activities_attributes: [{name: "Testing"}]}}
{:person=>{:name=>"Testing", :activities_attributes=>[{:name=>"Testing"}]}}


>> Person.create(params[:person])
   (0.1ms)  BEGIN
  SQL (6.5ms)  INSERT INTO "people" ("name", "created_at", "updated_at") VALUES (, , ) RETURNING "id"  [["name", "Testing"], ["created_at", 2016-07-13 21:30:45 UTC], ["updated_at", 2016-07-13 21:30:45 UTC]]
  SQL (12.5ms)  INSERT INTO "activities" ("person_id", "name", "created_at", "updated_at") VALUES (, , , ) RETURNING "id"  [["person_id", 37], ["name", "Testing"], ["created_at", 2016-07-13 21:30:45 UTC], ["updated_at", 2016-07-13 21:30:45 UTC]]
   (2.9ms)  COMMIT
#<Person id: 37, name: "Testing", age: nil, adult: nil, created_at: "2016-07-13 21:30:45", updated_at: "2016-07-13 21:30:45">

此页面显示了在 Rails 5 中发生的更改以产生此行为。

http://blog.bigbinary.com/2016/02/15/rails-5-makes-belong-to-association-required-by-default.html

使用 optional: true 并不是真正正确的解决方案 - 这是一种变通方法。 accepts_nested_attributes_for in Rails 5.1.1 之前的 5 个版本存在错误。参见 https://github.com/rails/rails/issues/25198 and Trouble with accepts_nested_attributes_for in Rails 5.0.0.beta3, -api option

解决方案是使用 inverse_of: 选项,或者更好的是,升级到 Rails 5.1.1。