Closed raphaelcm closed 12 years ago
Using Tenacity 0.5.4. Same issue occurs for MongoMapper-backed models. Haven't tested with any others.
Hi.
Could you please provide the class definitions for organization and avatar?
Thanks, John
They're both standard-issue ActiveRecord models that inherit from ActiveRecord::Base:
class Avatar < ActiveRecord::Base
has_attached_file (paperclip file parameters)
end
class Organization < ActiveRecord::Base
# some vanilla AR associations and validations
end
The Tenacity
module needs to be included in the target models as well. It adds some behavior to the models that allows tenacity to figure out how to setup the foreign keys.
Please include Tenacity
in your Avatar
and Organization
models and see if that fixes the problem.
Thanks, that resolved that but now I face a different issue:
class TenacityTest
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Slug
include Tenacity
t_belongs_to :organization #works
t_belongs_to :avatar #works
t_belongs_to :slideshow, :class_name => "Community::Slideshow" #fails
end
Slideshow is a standard AR model, the only difference is the namespacing and a custom table name.
class Community::Slideshow < ActiveRecord::Base
include Tenacity
set_table_name 'community_slideshows'
#...
end
Here's the exception:
> TenacityTest.new
NameError: wrong constant name Community::Slideshow
from /var/bundler/turtle/ruby/1.8/gems/tenacity-0.5.4/lib/tenacity/association.rb:73:in `const_get'
from /var/bundler/turtle/ruby/1.8/gems/tenacity-0.5.4/lib/tenacity/association.rb:73:in `associate_class'
from /var/bundler/turtle/ruby/1.8/gems/tenacity-0.5.4/lib/tenacity/orm_ext/helpers.rb:9:in `id_class_for'
from /var/bundler/turtle/ruby/1.8/gems/tenacity-0.5.4/lib/tenacity/orm_ext/mongoid.rb:94:in `_t_initialize_belongs_to_association'
from /var/bundler/turtle/ruby/1.8/gems/tenacity-0.5.4/lib/tenacity/associations/belongs_to.rb:36:in `initialize_belongs_to_association'
from /var/bundler/turtle/ruby/1.8/gems/tenacity-0.5.4/lib/tenacity/class_methods.rb:274:in `t_belongs_to'
from /my/app/models/tenacity_test.rb:9
...
I just pushed a commit that should address this issue
c24a35aeb57f0cd3719352ac4f63781d4cf0adef
Would you mind testing it out? If it solves your issue, I'll cut a new version of Tenacity.
Thanks for such a fast response! I'll test it out now. Hopefully I can familiarize myself enough with the codebase to contribute some fixes down the line.
Ok, just tested it out. Getting a different error now. Using same class definitions as above:
> t = TenacityTest.new
=> #<TenacityTest _id: 4f7b50c5e628f82349000005, created_at: nil, updated_at: nil, community/slideshow_id: nil, avatar_id: nil, _type: nil, organization_id: nil>
> t.avatar = Avatar.last
> t.organization = Organization.last
> t.slideshow = Community::Slideshow.last
> t
=> #<TenacityTest _id: 4f7b50c5e628f82349000005, created_at: nil, updated_at: nil, community/slideshow_id: 80145, avatar_id: 280, _type: nil, organization_id: 15189>
> t.valid?
=> true
> t.save
NoMethodError: undefined method `find_by_id' for #<Class:0xab501a8>
from /var/bundler/turtle/ruby/1.8/gems/activerecord-3.0.7/lib/active_record/base.rb:984:in `method_missing'
from /var/bundler/turtle/ruby/1.8/bundler/gems/tenacity-c24a35aeb57f/lib/tenacity/orm_ext/activerecord.rb:60:in `_t_find'
from /var/bundler/turtle/ruby/1.8/bundler/gems/tenacity-c24a35aeb57f/lib/tenacity/instance_methods.rb:23:in `_t_verify_associates_exist'
from /var/bundler/turtle/ruby/1.8/bundler/gems/tenacity-c24a35aeb57f/lib/tenacity/instance_methods.rb:19:in `each'
from /var/bundler/turtle/ruby/1.8/bundler/gems/tenacity-c24a35aeb57f/lib/tenacity/instance_methods.rb:19:in `_t_verify_associates_exist'
from /var/bundler/turtle/ruby/1.8/bundler/gems/tenacity-c24a35aeb57f/lib/tenacity/orm_ext/mongoid.rb:79:in `_callback_before_1683'
from /var/bundler/turtle/ruby/1.8/gems/activesupport-3.0.7/lib/active_support/callbacks.rb:422:in `_run_save_callbacks'
from /var/bundler/turtle/ruby/1.8/gems/activesupport-3.0.7/lib/active_support/callbacks.rb:94:in `send'
from /var/bundler/turtle/ruby/1.8/gems/activesupport-3.0.7/lib/active_support/callbacks.rb:94:in `run_callbacks'
from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence/insertion.rb:24:in `prepare'
from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence/insertion.rb:22:in `tap'
from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence/insertion.rb:22:in `prepare'
from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence/operations/insert.rb:26:in `persist'
from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence.rb:44:in `insert'
from /var/bundler/turtle/ruby/1.8/gems/mongoid-2.2.0/lib/mongoid/persistence.rb:149:in `save'
from (irb):36
Interesting. This implies that the ActiveRecord based class in the association does not respond to find_by_id
. Does either Avatar
, Organization
, or Community::Slideshow
not have a field named id
in their respective table? Perhaps one uses a primary key of a different name?
Ah yes. Community::Slideshow is a legacy model and its PK is show_id
. I created a class method find_by_id
that wraps find_by_show_id
and it works!
One question though, the foreign key field is community/slideshow_id
. Shouldn't it be slideshow_id
(to be consistent with how AR names FK fields)?
Yeah, it probably should. As you may have guessed, it looks like Tenacity doesn't handle name spaced classes well. For now, you should be able to do the following
t_belongs_to :slideshow, :class_name => "Community::Slideshow", :foreign_key => "slideshow_id"
Great. Thanks so much for your help.
No problem. I'll take a stab at fixing the foreign key issue before cutting the new version of Tenacity.
Let me know if you run into any other issues.
I just pushed a fix that should take care of the foreign key issue (ac4e7ff7b98f3c203a9f357415a3b926297d3c54). Would you mind giving it a try before I cut the new version of Tenacity?
Works! Thanks again.
> t = TenacityTest.new
=> #<TenacityTest _id: 4f7ef650e628f802e1000002, slideshow_id: nil, created_at: nil, updated_at: nil, avatar_id: nil, _type: nil, organization_id: nil>
> t.slideshow = Community::Slideshow.last
=> #<Community::Slideshow id: 78, department_id: 162, created_at: "2012-02-22 17:39:58", updated_at: "2012-04-06 13:45:22", slideshowable_id: "4f7da1b6e628f85988000001", slideshowable_type: "CampusHub">
> t
=> #<TenacityTest _id: 4f7ef650e628f802e1000002, slideshow_id: 78, created_at: nil, updated_at: nil, avatar_id: nil, _type: nil, organization_id: nil>
Fixed in version 0.5.5
Steps to reproduce:
Expected behavior: tt object should have getters and setters for both organization and avatar.
Actual behavior:
NOTE: TenacityTest works just fine with only one
t_belongs_to
association.