I am using Rails 5.0.0.beta3, building an API-only app using the -app option on rails new, and I am having trouble with accepts_nested_attributes_for.
In my app, a create (or a new, then a save!) of an object with nested attributes fails, with a message that the parent parent object must exist.
To test, I made a new app and used just the test case with members and posts in the ANAF documentation:
class Member < ApplicationRecord
has_many :posts
accepts_nested_attributes_for :posts
end
and
class Post < ApplicationRecord
belongs_to :member
end
(These class definitions were generated by the Rails scaffold generator, so the inherit from ApplicationRecord, rather than ActiveRecord::Base, but per this post, that is not significant.)
With those classed defined, and matching migrations created and run, I launch a Rails console and follow the steps in the doc:
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"}]}}
And then:
>> member = Member.create(params[:member])
(0.2ms) BEGIN
(0.4ms) ROLLBACK
#<Member id: nil, name: "joe", created_at: nil, updated_at: nil>
No joy!
When I split the create into new, then save!, I get the same result, with a somewhat clearer error:
>> member = Member.new(params[:member])
#<Member id: nil, name: "joe", created_at: nil, updated_at: nil>
member.save!
(15.0ms) BEGIN ActiveRecord::RecordInvalid: Validation failed: Posts member must exist
from /Users/pauldavis/.rvm/gems/ruby-2.2.4/bundler/gems/rails-b785064958f9/activerecord/lib/active_record/validations.rb:78:inraise_validation_error'
save!' from /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
block in save!' from /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
block in transaction' from /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
transaction' from /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' from /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!' from (irb):14 from /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' (0.2ms) ROLLBACK from /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!' from /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
' from /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
' from -e:1:inload' from -e:1:in
'
Any thoughts on why this sample code in the documentation is be working? Could something be wrong in my environment? Does the -api option break something in ActiveRecord? BTW, I am using PostgreSQL
Thanks!
optional:
parameter should be mentioned in the docs, because it is required to make the code work as shown. Perhaps the docs should also be updated changing the superclass to ApplicationRecord, too, though that seems less compelling. – PJD Barna