rails 5 accepts_nested_attributes 不工作
rails 5 accepts_nested_attributes Not Working
我只是在试验 Rails 5,然后发现了 accepts_nested_attributes_for。但我无法让它工作。 我做错了什么?
这是我的模型:
- 人
- 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。
我只是在试验 Rails 5,然后发现了 accepts_nested_attributes_for。但我无法让它工作。 我做错了什么?
这是我的模型:
- 人
- 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。