Closed mattiassvedhem closed 12 years ago
If I create car_id and add the association manually it does work. However it's not persisted. I use devise for authentication and if I log out the car_id will be wiped from the wheel object. This might be a problem with devise or mongoid though?
It's strange though cause it's only the car_id that's wiped. Indicating that it is indeed a problem with Tenacity.
Hi. I'm sorry, but I'm unable to reproduce this error.
My Gemfile
source 'http://rubygems.org'
gem 'rails', '3.1.1'
gem 'tenacity', '0.5.3'
gem 'mysql2', '0.3.10'
gem 'couchrest'
gem 'couchrest_extended_document'
gem 'mongo', '1.4.0'
gem 'mongoid', '2.2.4'
gem 'bson', '1.4.0'
gem 'bson_ext', '1.4.0'
With those dependencies, I am able to do the following in rails console:
[~/dev/personal/tenacity_rails3] $ rails console
Loading development environment (Rails 3.1.1)
ruby-1.8.7-p352 :001 > car = Car.create
Wheel Load (0.3ms) SELECT `wheels`.* FROM `wheels` WHERE (car_id = '4ecb9ffc904f562ced000001')
=> #<Car _id: 4ecb9ffc904f562ced000001, _type: nil>
ruby-1.8.7-p352 :002 > wheel_1 = Wheel.create
(0.1ms) BEGIN
SQL (0.2ms) INSERT INTO `wheels` (`car_id`, `created_at`, `updated_at`) VALUES (NULL, '2011-11-22 13:13:33', '2011-11-22 13:13:33')
(0.5ms) COMMIT
=> #<Wheel id: 4, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">
ruby-1.8.7-p352 :003 > wheel_2 = Wheel.create
(0.1ms) BEGIN
SQL (0.1ms) INSERT INTO `wheels` (`car_id`, `created_at`, `updated_at`) VALUES (NULL, '2011-11-22 13:13:33', '2011-11-22 13:13:33')
(0.1ms) COMMIT
=> #<Wheel id: 5, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">
ruby-1.8.7-p352 :004 > wheel_3 = Wheel.create
(0.1ms) BEGIN
SQL (0.1ms) INSERT INTO `wheels` (`car_id`, `created_at`, `updated_at`) VALUES (NULL, '2011-11-22 13:13:33', '2011-11-22 13:13:33')
(0.2ms) COMMIT
=> #<Wheel id: 6, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">
ruby-1.8.7-p352 :005 > wheels = [wheel_1, wheel_2, wheel_3]
=> [#<Wheel id: 4, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">, #<Wheel id: 5, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">, #<Wheel id: 6, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">]
ruby-1.8.7-p352 :006 > car.wheels = wheels
=> [#<Wheel id: 4, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">, #<Wheel id: 5, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">, #<Wheel id: 6, car_id: nil, created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">]
ruby-1.8.7-p352 :007 > car.save
Wheel Load (0.2ms) SELECT `wheels`.* FROM `wheels` WHERE (car_id = '4ecb9ffc904f562ced000001')
Wheel Load (0.2ms) SELECT `wheels`.* FROM `wheels` WHERE `wheels`.`id` = 4 LIMIT 1
(0.1ms) BEGIN
(0.2ms) UPDATE `wheels` SET `updated_at` = '2011-11-22 13:13:33', `car_id` = '4ecb9ffc904f562ced000001' WHERE `wheels`.`id` = 4
(0.2ms) COMMIT
Wheel Load (0.2ms) SELECT `wheels`.* FROM `wheels` WHERE `wheels`.`id` = 5 LIMIT 1
(0.0ms) BEGIN
(0.1ms) UPDATE `wheels` SET `updated_at` = '2011-11-22 13:13:33', `car_id` = '4ecb9ffc904f562ced000001' WHERE `wheels`.`id` = 5
(0.2ms) COMMIT
Wheel Load (0.2ms) SELECT `wheels`.* FROM `wheels` WHERE `wheels`.`id` = 6 LIMIT 1
(0.0ms) BEGIN
(0.2ms) UPDATE `wheels` SET `updated_at` = '2011-11-22 13:13:33', `car_id` = '4ecb9ffc904f562ced000001' WHERE `wheels`.`id` = 6
(0.2ms) COMMIT
=> true
ruby-1.8.7-p352 :008 > car
=> #<Car _id: 4ecb9ffc904f562ced000001, _type: nil>
ruby-1.8.7-p352 :009 > exit
[~/dev/personal/tenacity_rails3] $
[~/dev/personal/tenacity_rails3] $ rails console
Loading development environment (Rails 3.1.1)
ruby-1.8.7-p352 :001 >
ruby-1.8.7-p352 :002 > car = Car.find "4ecb9ffc904f562ced000001"
=> #<Car _id: 4ecb9ffc904f562ced000001, _type: nil>
ruby-1.8.7-p352 :003 > car.wheels
(0.3ms) SELECT id FROM wheels WHERE car_id = '4ecb9ffc904f562ced000001'
Wheel Load (0.2ms) SELECT `wheels`.* FROM `wheels` WHERE (id in (4,5,6))
=> [#<Wheel id: 4, car_id: "4ecb9ffc904f562ced000001", created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">, #<Wheel id: 5, car_id: "4ecb9ffc904f562ced000001", created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">, #<Wheel id: 6, car_id: "4ecb9ffc904f562ced000001", created_at: "2011-11-22 13:13:33", updated_at: "2011-11-22 13:13:33">]
ruby-1.8.7-p352 :004 >
Can you explain what you mean by "this was tested with a single model"?
John
And, here are my classes:
class Car
include Mongoid::Document
include Tenacity
t_has_many :wheels
t_has_one :dashboard
end
class Wheel < ActiveRecord::Base
include Tenacity
t_belongs_to :car
end
What I mean with "this was tested with a single model" is that I didn't use STI or Polymorphic associations. You are right, it does work that way.
I have the t_belongs_to call in the Mongoid model.
class Wheel
include Mongoid::Document
include Tenacity
t_belongs_to :car
end
class Car < ActiveRecord::Base
include Tenacity
t_has_many :wheels
end
This works:
irb(main):022:0> car = Car.first
Car Load (0.8ms) SELECT `cars`.* FROM `cars` LIMIT 1
=> #<Car id: 1, name: "Ferrari">
irb(main):023:0> wheel_1 = Wheel.last
=> #<Wheel _id: 4ebe6a8d66eaa7e4aa000002, _type: nil, name: "Wheel1", car_id: nil>
irb(main):024:0> wheel_2 = Wheel.first
=> #<Wheel _id: 4ebba80866eaa75c7a000003, _type: nil, name: "Wheel2", car_id: nil>
irb(main):025:0> wheels = [wheel_1, wheel_2]
=> [#<Wheel _id: 4ebe6a8d66eaa7e4aa000002, _type: nil, name: "Wheel1", car_id: nil>, #<Wheel _id: 4ebba80866eaa75c7a000003, _type: nil, name: "Wheel2", car_id: nil>]
irb(main):026:0> car.wheels = wheels
=> [#<Wheel _id: 4ebe6a8d66eaa7e4aa000002, _type: nil, name: "Wheel1", car_id: nil>, #<Wheel _id: 4ebba80866eaa75c7a000003, _type: nil, name: "Wheel2", car_id: nil, slug: "haket">]
irb(main):027:0> car.save
(0.2ms) BEGIN
Car Load (0.6ms) SELECT `cars`.* FROM `cars` WHERE `cars`.`id` = 1 LIMIT 1
Car Load (0.4ms) SELECT `cars`.* FROM `cars` WHERE `cars`.`id` = 1 LIMIT 1
(0.2ms) COMMIT
=> true
irb(main):028:0>
irb(main):029:0> car.wheels
User Load (0.5ms) SELECT `cars`.* FROM `cars` LIMIT 1
=> [#<Wheel _id: 4ebba80866eaa75c7a000003, _type: nil, name: "Wheel1", car_id: 1>, #<Wheel _id: 4ebe6a8d66eaa7e4aa000002, _type: nil, name: "Wheel2", car_id: 1>]
This doesn't set the car_id:
irb(main):015:0> wheel = Wheel.create
=> #<Wheel _id: 4ecba73166eaa75371000002, _type: nil, name: nil, car_id: nil>
irb(main):016:0> car.wheels << wheel
=> [#<Wheel _id: 4ebe6a8d66eaa7e4aa000002, _type: nil, name: "Wheel1", car_id: 1>, #<Wheel _id: 4ebba80866eaa75c7a000003, _type: nil, name: "Wheel2", car_id: 1>, #<Wheel _id: 4ecba73166eaa75371000002, _type: nil, name: nil, car_id: nil>]
irb(main):017:0>
irb(main):017:0> car.save
(0.2ms) BEGIN
Car Load (0.6ms) SELECT `cars`.* FROM `cars` WHERE `cars`.`id` = 1 LIMIT 1
Car Load (0.4ms) SELECT `cars`.* FROM `cars` WHERE `cars`.`id` = 1 LIMIT 1
(0.2ms) ROLLBACK
Mongoid::Errors::DocumentNotFound: translation missing: sv_SE.mongoid.errors.messages.document_not_found
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/mongoid-2.2.4/lib/mongoid/document.rb:149:in `reload'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/orm_ext/mongoid.rb:112:in `_t_reload'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/associate_proxy.rb:52:in `method_missing'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/associations/has_many.rb:142:in `block in establish_relationship_in_target_objects'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/associates_proxy.rb:61:in `block in method_missing'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/associates_proxy.rb:61:in `each'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/associates_proxy.rb:61:in `method_missing'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/associations/has_many.rb:141:in `establish_relationship_in_target_objects'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/associations/has_many.rb:109:in `_t_save_associates'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/tenacity-0.5.3/lib/tenacity/orm_ext/activerecord.rb:90:in `block in _t_initialize_has_many_association'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/callbacks.rb:422:in `_run_save_callbacks'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/callbacks.rb:81:in `run_callbacks'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/callbacks.rb:264:in `create_or_update'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/persistence.rb:37:in `save'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/validations.rb:50:in `save'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/attribute_methods/dirty.rb:22:in `save'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:241:in `block (2 levels) in save'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:208:in `transaction'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:241:in `block in save'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:252:in `rollback_active_record_state!'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:240:in `save'
from (irb):17
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/railties-3.1.1/lib/rails/commands/console.rb:45:in `start'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/railties-3.1.1/lib/rails/commands/console.rb:8:in `start'
from /Users/yeggeps/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/railties-3.1.1/lib/rails/commands.rb:40:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'irb(main):018:0>
In the proccess I discovered that associations to Devise models dissapear when I destroy a session and create a new one. Maybe I shall start a new ticket about that.
Thanks.
Sorry, I still cannot reproduce the error.
I changed my Wheel and Car models to look like what you have listed above. I then tried to reproduce the error using the steps described. In each case, car.wheels << wheel
successfully added a wheel association to the car, and the car_id was set successfully.
Is there any way you can create a failing test case on a branch that I can take a look at?
John
I created a fresh project where << works without problems. The problems I have is probably related to some other gem in combination with Tenacity. I would think it's Devise since all associations are destroyed on session destroy / session create.
If you can identify which gem is causing the issue, I could look at that gem's source and try to identify the conflict.
Closing for now. Feel free to re-open if you identify the gem that is causing the conflict.
When I follow this pattern:
Tenacity doesn't update the car_id in wheels. And if I try to access car.wheels I just get an empty array.
Seems to work flawless with t_has_one.
I tried to use the auto_save option, but i reckon it's not for this purpose? I also tried to manually specify the foreign_key, but that didn't help either.
This was tested with a single model and these gems: