我正在使用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:inraise_validation_error'
save!&#39; 来自/Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/attribute_methods/dirty.rb:30:in
from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/validations.rb:50:insave!' 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:inblock 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:inwithin_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:intransaction' 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:insave!' 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:instart' 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:inconsole' 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:inrun' 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:inrequire' 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
谢谢!
答案 0 :(得分:9)
我也遇到了同样的问题
似乎规范已经从Rails 5改变。
通过选择,以及之前和相同的操作。
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
的最后一个(注释掉的行)有一些问题,但希望这会让你知道如何解决这个问题。