parental_control icon indicating copy to clipboard operation
parental_control copied to clipboard

Namespaced classes produce an invalid reciprocal method name

Open adonaldson opened this issue 12 years ago • 1 comments

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!

adonaldson avatar Mar 27 '12 12:03 adonaldson

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).

h-lame avatar Mar 27 '12 13:03 h-lame