parental_control
parental_control copied to clipboard
Namespaced classes produce an invalid reciprocal method name
Hey there,
I've been working on a project (rails 2.3.14) that uses your plugin and came across a strange issue when I was adding the Tolk engine. The Tolk models are namespaced (app/models/tolk/phrase.rb and Tolk::Phrase). The error (on any page you hit) was:
(eval):4:in `set_reciprocal_instance': compile error
(eval):2: syntax error, unexpected '/', expecting '\n' or ';'
...on_for_translations_from_tolk/phrase
^
(eval):4: syntax error, unexpected kEND, expecting $end
Looking through lib/parental_control.rb
I found that cached_reciprocal_association_method_name
was using the instance class name underscored to build up a key. Unfortunately in this case the key-part it was coming up with was 'tolk/phrase'.
I was able to work around the issue by (brace yourself) replacing the slash with an underscore (again, in lib/parental_control.rb
).
def cached_reciprocal_assocation_method_name(record, instance)
instance_class_name = instance.class.name.underscore.gsub(/\//, '_')
:"best_guess_reciprocal_association_for_#{@reflection.name}_from_#{instance_class_name}"
end
I'll admit that a lot of the code in the plugin is over my head, so I thought i'd share this with you to see if you had any insights.
Cheers!
I suspect there's a better way of asking a model class for it's underscored name (perhaps table_name?) and have that deal with slashes caused by namespacing. That said, basically it probably boils down to the same thing so I expect your change is fine.
You might want to see if the :inverse_of options of Rails let you achieve what parental_control achieve. I think :inverse_of is in rails 2.3, but I can't remember (it's been a while). The main difference is that parental_control is automatic, whereas with :inverse_of you have to specify the relationships.
e.g.
class Foo < AR::Base
belongs_to :bar
end
class Bar < AR::Base
has_one :foo
end
(with parental_control) vs.
class Foo < AR::Base
belongs_to :bar, :inverse_of => :foo
end
class Bar < AR::Base
has_one :foo, :inverse_of => :bar
end
(with :inverse_of).
I assume that the :inverse_of stuff copes better with the namespaced models, as even though I wrote it originally, it's properly integrated with rails and probably has more eyes over it so bugs like this will have been caught earlier. (Perhaps).