jwood / tenacity

A database client independent way of managing relationships between models backed by different databases.
MIT License
118 stars 17 forks source link

t_has_many association not working #41

Closed glarrai1 closed 11 years ago

glarrai1 commented 11 years ago

On this analog case:

One-to-many

Use t_has_many in the base, and t_belongs_to in the associated model.

class Manager < ActiveRecord::Base include Tenacity t_has_many :employees end

class Employee include MongoMapper::Document include Tenacity t_belongs_to :manager # foreign key - manager_id end

It gives me this error:

ruby-1.9.3-p0 :005 > t.mongo_trackpoints ArgumentError: wrong number of arguments (2 for 1) from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/moped-1.2.9/lib/moped/collection.rb:42:in find' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/orm_ext/mongoid.rb:74:in_t_find_all_ids_by_associate' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/associations/has_many.rb:30:in _t_get_associate_ids' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/associations/has_many.rb:38:inhas_many_associates' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/class_methods.rb:390:in block (2 levels) in t_has_many' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/instance_methods.rb:71:inget_associate' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/class_methods.rb:389:in block in t_has_many' from (irb):5 from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/railties-3.2.7/lib/rails/commands/console.rb:47:instart' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/railties-3.2.7/lib/rails/commands/console.rb:8:in start' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/railties-3.2.7/lib/rails/commands.rb:41:in<top (required)>' from script/rails:6:in require' from script/rails:6:in

'

jwood commented 11 years ago

This looks like an incompatibility with the moped MongoDB driver. The "standard" ruby MongoDB driver (mongo) takes 2 parameters to find, but it looks like moped only supports one.

Tenacity uses this second parameter to specify that we would only like the id field back in the results.

https://github.com/jwood/tenacity/blob/master/lib/tenacity/orm_ext/mongoid.rb#L74

This line could probably be changed to drop the second parameter to find. I don't think any other changes would be necessary. Feel free to give that a shot. If that works, I can cut a new version of Tenacity.

glarrai1 commented 11 years ago

It works replacing the line to: results = collection.find({property => _t_serialize(id)}).to_a , but still one issue...

t = Track.first (this an Active Record Object; and t_has_many :mongo_trackpoints) p = MongoTrackpoint.first (this is an Mongoid Object, and t_belongs_to :track)

if i do: p.track = t p.save

It works..but: t.mongo_trackpoints << p t.save

ERROR!

ruby-1.9.3-p0 :060 > t.save (0.1ms) BEGIN (0.1ms) ROLLBACK Mongoid::Errors::DocumentNotFound: Problem: Document(s) not found for class MongoTrackpoint with id(s) all, {:conditions=>{"track_id"=>2}}. Summary: When calling MongoTrackpoint.find with an id or array of ids, each parameter must match a document in the database or this error will be raised. The search was for the id(s): all, {:conditions=>{"track_id"=>2}} ... (2 total) and the following ids were not found: all, {:conditions=>{"track_id"=>2}}. Resolution: Search for an id that is in the database or set the Mongoid.raise_not_found_error configuration option to false, which will cause a nil to be returned instead of raising this error when searching for a single id, or only the matched documents when searching for multiples. from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/mongoid-3.0.12/lib/mongoid/criteria.rb:583:in check_for_missing_documents!' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/mongoid-3.0.12/lib/mongoid/criteria.rb:177:inexecute_or_raise' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/mongoid-3.0.12/lib/mongoid/criteria.rb:243:in find' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/mongoid-3.0.12/lib/mongoid/finders.rb:61:infind' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/orm_ext/mongoid.rb:70:in _t_find_all_by_associate' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/associations/has_many.rb:134:inget_current_associates' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/associations/has_many.rb:104:in _t_save_associates' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/tenacity-0.5.8/lib/tenacity/orm_ext/activerecord.rb:90:inblock in _t_initialize_has_many_association' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activesupport-3.2.7/lib/active_support/callbacks.rb:453:in _run__560808238__save__864792655__callbacks' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activesupport-3.2.7/lib/active_support/callbacks.rb:405:in__run_callback' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activesupport-3.2.7/lib/active_support/callbacks.rb:385:in _run_save_callbacks' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activesupport-3.2.7/lib/active_support/callbacks.rb:81:inrun_callbacks' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/callbacks.rb:264:in create_or_update' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/persistence.rb:84:insave' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/validations.rb:50:in save' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/attribute_methods/dirty.rb:22:insave' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/transactions.rb:241:in block (2 levels) in save' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/transactions.rb:295:inblock in with_transaction_returning_status' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in transaction' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/transactions.rb:208:intransaction' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/transactions.rb:293:in with_transaction_returning_status' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/transactions.rb:241:inblock in save' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/transactions.rb:252:in rollback_active_record_state!' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/activerecord-3.2.7/lib/active_record/transactions.rb:240:insave' from (irb):60 from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/railties-3.2.7/lib/rails/commands/console.rb:47:in start' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/railties-3.2.7/lib/rails/commands/console.rb:8:instart' from /home/redvel2/.rvm/gems/ruby-1.9.3-p0@tsp/gems/railties-3.2.7/lib/rails/commands.rb:41:in <top (required)>' from script/rails:6:inrequire'

jwood commented 11 years ago

Great, I'm glad the first issue is resolved. I should have a patch for that in master by the end of the day.

I have a theory as to why the second issue is happening. I believe it is because t.mongo_trackpoints doesn't have anything in it when you try to add something to it using t.mongo_trackpoints << p (which is obviously a bug in Tenacity). If this is the case, it is an issue with the core of Tenacity, and does not only affect the MongoDB adapters. So setting Mongoid.raise_not_found_error to true wouldn't truly fix the issue.

I should have some time over the next couple of days to write a test to prove my theory, and then start looking into a fix. In the meantime, you should be able to use t.mongo_trackpoints = [p] for this particular case as a work around.

glarrai1 commented 11 years ago

Thanks for the upgrade!

About the other issue, i tried t.mongo_trackpoints = [p] It partialy works (but as the same as t.mongo_trackpoints << p ; when you are saving t.save is when it fails) Hope you will find the solution to this too, thanks!

jwood commented 11 years ago

Hmmm....t.mongo_trackpoints = [p] should have worked if my theory was correct. I guess it isn't.

I do have tests that cover this scenario, and they are passing. However, I haven't worked on Tenacity in a while, and the tests are still running against older versions of several libraries (see https://github.com/jwood/tenacity/blob/master/tenacity.gemspec for details).

In particular, the tests are running against Mongoid 2.x, and you're using Mongoid 3.x. I bet this is causing the issue, because check_for_missing_documents!, the method that is raising the exception, doesn't seem to exist in Mongoid 2.x.

Upgrading Tenacity to support a new version of Mongoid could prove a bit more time consuming. Feel free to fork the codebase and give it a shot. Otherwise, I'll try and get to it sometime this week.

jwood commented 11 years ago

I just pushed some changes that should take care of this. Can you try pulling the code from master, and see if it corrects your issue?

glarrai1 commented 11 years ago

Yes, it works perfect now..thanks!

jwood commented 11 years ago

Great. I have some more testing to do, and then I'll be able to release a new version. I should hopefully get to it this week.

jwood commented 11 years ago

This is fixed in version 0.6.0