rails 5 accepts_nested_attributes不工作

时间:2016-07-13 19:36:08

标签: ruby-on-rails-5

我只是尝试使用Rails 5,并且遇到了 accepts_nested_attributes_for 。但我无法让它发挥作用。 我做错了什么

以下是我的模特:

  1. 活动
  2. 以下是SQL表定义

    型号代码

    class Person < ApplicationRecord
      has_many :activities
      accepts_nested_attributes_for :activities
    end
    
    
    class Activity < ApplicationRecord
      belongs_to :person
    end
    

    阅读API文档(accepts_nested_attributes_for

    我创建了一个params哈希,并尝试将其提交给Person Class。

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

    当我尝试运行此特定代码时,不是创建名为&#34; Joe&#34;的新人员记录,而是在&#34;徒步旅行&#34;的活动下创建新的关联记录,而不是简单的失败。 / p>

    >> 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 ($1, $2, $3) 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 $1  [["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" = $1 LIMIT $2  [["id", 35], ["LIMIT", 1]]
      SQL (13.0ms)  INSERT INTO "activities" ("person_id", "name", "created_at", "updated_at") VALUES ($1, $2, $3, $4) 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" = $1  [["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>]>
    

    人员表

    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)
    

    活动表

    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)
    

2 个答案:

答案 0 :(得分:1)

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

我是如何工作的,看看这个问题是否被隔离到rails 5.我创建了一个Rails 4.2应用程序,具有相同的确切代码,它工作

一旦我开始工作,我就在网上看了一下这些帖子,看看我是否能找到为什么会出现这种情况。这些是帮助我的资源:

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 ($1, $2, $3) 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 ($1, $2, $3, $4) 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

答案 1 :(得分:0)

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

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