-
-
Notifications
You must be signed in to change notification settings - Fork 592
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
accepts_nested_attributes_for #185
Comments
"When i try to add multiple authors" Thanks for the bug report. Can you show me code that shows me exactly how you're trying to do that? Also, please show me your whole stack trace, not just the error message. I am more than happy to help you but if I have send you multiple messages to figure out what's going on in your code, or spend 30 minutes figuring out how to reproduce your problem, then I can't help you because I am literally too busy. |
Ok, i'm sorry, you're right. I create a repository to reproduce the error. I am using Rails 3.1. I try to explain it here in more detail. class Author < ActiveRecord::Base
extend FriendlyId
belongs_to :publication, :polymorphic => true
friendly_id :name, :use => :slugged
end class Book < ActiveRecord::Base
has_many :authors, :as => :publication
accepts_nested_attributes_for :authors
end I added a unique index for slug column. In books controller: def new
@book = Book.new
(1..3).each do
@book.authors.build
end
respond_to do |format|
format.html # new.html.erb
format.json { render json: @book }
end
end I have a form for Book model, which i use to add a book title and author names. accepts_nested_attributes_for is used to add author names. For simplicity i just build 3 authors. So i have a form which has 4 fields, one for book title and 3 for author names. When i try to add multiple authors with the same name, i got an exception. SQLite3::ConstraintException in BooksController#create
column slug is not unique Full trace: activerecord (3.1.0) lib/active_record/connection_adapters/sqlite_adapter.rb:110:in `close'
activerecord (3.1.0) lib/active_record/connection_adapters/sqlite_adapter.rb:110:in `block in clear_cache!'
activerecord (3.1.0) lib/active_record/connection_adapters/sqlite_adapter.rb:110:in `each'
activerecord (3.1.0) lib/active_record/connection_adapters/sqlite_adapter.rb:110:in `clear_cache!'
activerecord (3.1.0) lib/active_record/connection_adapters/sqlite_adapter.rb:104:in `disconnect!'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:214:in `block in clear_reloadable_connections!'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:213:in `each'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:213:in `clear_reloadable_connections!'
activesupport (3.1.0) lib/active_support/core_ext/module/synchronization.rb:35:in `block in clear_reloadable_connections_with_synchronization!'
/home/emre/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
activesupport (3.1.0) lib/active_support/core_ext/module/synchronization.rb:34:in `clear_reloadable_connections_with_synchronization!'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:391:in `block in clear_reloadable_connections!'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:391:in `each_value'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:391:in `clear_reloadable_connections!'
activerecord (3.1.0) lib/active_record/connection_adapters/abstract/connection_specification.rb:123:in `clear_reloadable_connections!'
activerecord (3.1.0) lib/active_record/railtie.rb:84:in `block (3 levels) in <class:Railtie>'
activesupport (3.1.0) lib/active_support/callbacks.rb:404:in `_run_cleanup_callbacks'
activesupport (3.1.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.1.0) lib/action_dispatch/middleware/reloader.rb:72:in `rescue in call'
actionpack (3.1.0) lib/action_dispatch/middleware/reloader.rb:67:in `call'
rack (1.3.5) lib/rack/sendfile.rb:101:in `call'
actionpack (3.1.0) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.1.0) lib/action_dispatch/middleware/show_exceptions.rb:47:in `call'
railties (3.1.0) lib/rails/rack/logger.rb:13:in `call'
rack (1.3.5) lib/rack/methodoverride.rb:24:in `call'
rack (1.3.5) lib/rack/runtime.rb:17:in `call'
activesupport (3.1.0) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.3.5) lib/rack/lock.rb:15:in `call'
actionpack (3.1.0) lib/action_dispatch/middleware/static.rb:53:in `call'
railties (3.1.0) lib/rails/engine.rb:455:in `call'
railties (3.1.0) lib/rails/rack/content_length.rb:16:in `call'
railties (3.1.0) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.3.5) lib/rack/handler/webrick.rb:59:in `service'
/home/emre/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/home/emre/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/home/emre/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread' Maybe request parameters will help: {"utf8"=>"✓",
"authenticity_token"=>"sQmBDRqvOlLqdC9lckojgGMyWELhd6NCdyu4LOGcWQU=",
"book"=>{"title"=>"book title",
"authors_attributes"=>{"0"=>{"name"=>"emre"},
"1"=>{"name"=>"emre"},
"2"=>{"name"=>"kutlu"}}},
"commit"=>"Create Book"} I hope this helps. |
Awesome, thanks for the extensive info. I'll take a look into it today. |
Sorry I've been slow to respond to this, I'll try to make time today to look into it some more. |
I just realized that we have a more basic problem. It is not related to accepts_nested_attributes_for. I am not sure it is a new issue or related to this one. From the previous models: Author.create(:name => "emre")
#<Author id: 1, name: "emre", slug: "emre">
Author.create(:name => "emre")
#<Author id: 2, name: "emre", slug: "emre--2">
last_author = Author.find(2)
last_author.save
#<Author id: 2, name: "emre", slug: "emre--2"> Everything is normal up to here. But when i save the first author: first_author = Author.find(1)
first_author.save
#<Author id: 1, name: "emre", slug: "emre--3"> Author.all
# [#<Author id: 1, name: "emre", slug: "emre--3">, #<Author id: 2, name: "emre", slug: "emre--2">] |
Some new info: Author.create(:name => "norman")
#<Author id: 3, name: "norman", slug: "norman">
Author.last.should_generate_new_friendly_id?
# true
I override def should_generate_new_friendly_id?
send("#{friendly_id_config.base}_changed?")
end |
Sorry for commenting so much but i think i got one step closer to the problem's reason. It is about callback chain. On So |
should_generate_new_friendly_id? should always return |
Please try your app against FriendlyId master now, I've added a change to address the resequencing issue. You were right - the callback chain was definitely a factor in the bug. Thanks again for the report. |
callback chain bug seems resolved but accepts_nested_attributes_for bug remains. |
Ok, so I've looked into this at length and it's not a simple problem to solve. I think the best course will be to generate the slug in a before_validation callback, and then generate the sequence in a before_save callback. Otherwise in cases like this, FriendlyId does two queries to check if a slug is being used before doing an insert, so it's impossible to detect collisions. |
For now I'm going to leave this issue documented but not fix it, as it would be too significant a change so close to a release, and there are some fairly simple workarounds. I've just added a commit that references this issue, and it can be reopened in the future. |
I am using "4.0.0.beta14". I have a form for Book model which also can add multiple authors. Author model's slug column has an unique index.
When i try to add multiple authors whose name is same, all authors try to get the same slug, so a "Mysql2::Error: Duplicate entry" occurs.
The text was updated successfully, but these errors were encountered: