Rails 5.0.0.beta3中的accepts_nested_attributes_for问题,-api选项

时间:2016-03-11 14:15:01

标签: ruby-on-rails postgresql activerecord ruby-on-rails-5

我正在使用Rails 5.0.0.beta3,使用rails new上的-app选项构建一个仅限API的应用程序,而我在使用accepts_nested_attributes_for时遇到了问题。

在我的应用程序中,具有嵌套属性的对象的创建(或新的,然后保存!)失败,并显示父父对象必须存在的消息。

为了测试,我制作了一个新的应用,只使用了ANAF documentation中的成员和帖子的测试用例:

class Member < ApplicationRecord  
  has_many :posts  
  accepts_nested_attributes_for :posts  
end  

class Post < ApplicationRecord
 belongs_to :member
end

(这些类定义是由Rails脚手架生成器生成的,所以继承自ApplicationRecord,而不是ActiveRecord :: Base,但是每this post,这并不重要。)

在定义了这些类别并创建并运行匹配的迁移后,我启动了一个Rails控制台并按照文档中的步骤进行操作:

params = { member: {
name: 'joe', posts_attributes: [
    { title: 'Kari, the awesome Ruby documentation browser!' },
    { title: 'The egalitarian assumption of the modern citizen' },
    { title: '', _destroy: '1' } # this will be ignored
]}}  

{:member=>{:name=>"joe", :posts_attributes=>[{:title=>"Kari, the awesome Ruby documentation browser!"}, {:title=>"The egalitarian assumption of the modern citizen"}, {:title=>"", :_destroy=>"1"}]}}

然后:

>> member = Member.create(params[:member])
 (0.2ms)  BEGIN
 (0.4ms)  ROLLBACK
#<Member id: nil, name: "joe", created_at: nil, updated_at: nil>

没有快乐!

当我将create拆分为new,然后保存!时,我得到了相同的结果,错误更明确:

>> member = Member.new(params[:member])  
#<Member id: nil, name: "joe", created_at: nil, updated_at: nil>
  
    

member.save!
       (15.0ms)BEGIN     ActiveRecord :: RecordInvalid:验证失败:帖子成员必须存在         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/validations.rb:78:in raise_validation_error'
from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/validations.rb:50:in
save!&#39;         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/attribute_methods/dirty.rb:30:in save!' from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/transactions.rb:324:in阻止保存!& #39;         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/transactions.rb:395:in block in with_transaction_returning_status' from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:233:in阻止交易&#39;         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb:189:in within_new_transaction' from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:233:in交易&#39 ;         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/transactions.rb:211:in transaction' from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/transactions.rb:392:in with_transaction_returning_status&#39;         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/transactions.rb:324:in save!' from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/suppressor.rb:45:in save!&#39;         来自(irb):14         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/railties/lib/rails/commands/console.rb:65:in start' from /Users/pauldavis/.rvm/gems/ruby-2.2.4 /bundler/gems/rails-b785064958f9/railties/lib/rails/commands/console_helper.rb:9:in start&#39;      (0.2ms)ROLLBACK         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/railties/lib/rails/commands/commands_tasks.rb:78:in console' from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/railties/lib/rails/commands/commands_tasks.rb:49:in run_command!&#39 ;         来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/railties/lib/rails/command.rb:20:in run' from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/railties/lib/rails/commands.rb:18:in&#39;         来自/Users/pauldavis/Documents/Projects/Active/Rails/curious/doko/m.0/test_anaf/bin/rails:9:in require' from /Users/pauldavis/Documents/Projects/Active/Rails/curious/doko/m.0/test_anaf/bin/rails:9:in&#39;         来自-e:1:load' from -e:1:in&#39;

  

有关为什么文档中的示例代码有效的任何想法?我的环境可能有问题吗? -api选项是否会破坏ActiveRecord中的某些内容?顺便说一下,我正在使用PostgreSQL

谢谢!

5 个答案:

答案 0 :(得分:9)

我也遇到了同样的问题 似乎规范已经从Rails 5改变。
通过选择,以及之前和相同的操作。

strings.Split

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

我的笨拙可能会说英语,但是......

答案 1 :(得分:4)

这是一个报告为rails#25198的回归。如前所述,您可以使用inverse_of作为解决方法。

计划在5.0.1中修复。

答案 2 :(得分:3)

我遇到了同样的问题,我在https://github.com/rails/rails/issues/18233

中找到了解决方案

添加

class Post < ApplicationRecord
belongs_to :member, required: false
end

Rails 5中的accepts_nested_attributes_for似乎存在问题,因此您需要将required: false添加到您的子模型中。

答案 3 :(得分:1)

我发现将inverse_of选项添加到关联允许accepts_nested_attributes工作。比猴子修补好,仍然允许关联验证

答案 4 :(得分:0)

我在我的Rails 5 beta 3应用程序中遇到accepts_nested_attributes_for的问题,看起来好像有问题。理想情况下,应该提交错误报告,但我们没有时间正确地完成它。我们有以下设置:

accepts_nested_attributes_for :attachments, allow_destroy: true

最终,我们不得不在模型中修补方法,如下所示:

  def attachments_attributes=(attributes)
    attributes.reject! do |_attachment|  
      if _attachment = Attachment.find(_attachment['id'])
        if _attachment.drop_id.nil?
          attachments << _attachment
          next true
        end
      end
      next false
    end
    # assign_nested_attributes_for_collection_association(:attachments, attributes)
  end

唯一的问题是assign_nested_attributes_for_collection_association的最后一个(注释掉的行)有一些问题,但希望这会让你知道如何解决这个问题。