Aakash Chopra
2007-Feb-11 05:53 UTC
method_missing in a AR child only catching 1 of several call
Hello - Why does a view including the following fragment: <% for column in User.content_columns %> <td><%=h user.send(column.name) %></td> <% end %> and the User model having the following defined: def method_missing(meth_id, *args, &blk) meth_name=meth_id.id2name puts("Calling: #{meth_name}") super end only result in the following output of one method call when there are several columns/attributes in the users table: Calling: name -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
George Ogata
2007-Feb-11 08:34 UTC
Re: method_missing in a AR child only catching 1 of several call
On 2/11/07, Aakash Chopra <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Hello - > > Why does a view including the following fragment: > > <% for column in User.content_columns %> > <td><%=h user.send(column.name) %></td> > <% end %> > > and the User model having the following defined: > > def method_missing(meth_id, *args, &blk) > meth_name=meth_id.id2name > puts("Calling: #{meth_name}") > super > end > > only result in the following output of one method call when there are > several columns/attributes in the users table: > > Calling: nameHi Aakash, ActiveRecord::Base defines read methods lazily. That is, until you call a method to read an attribute, the method won''t exist. Call a method to read an attribute, and it''ll hit AR::B''s method_missing hook, which defines all the read methods, and hence, subsequent calls to read methods won''t trigger method_missing. You can witness the effect in script/console:>> Thing.instance_methods(false)=> []>> Thing.new.name=> nil>> Thing.instance_methods(false)=> ["id?", "name?", "name", "value", "value?"] I''m not sure what you''re trying to do, but if you explain it, someone might be able to find something that works. :-) (Assuming this is a problem for you.) Regards, George. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
George Ogata wrote: . .> I''m not sure what you''re trying to do, but if you explain it, someone > might be able to find something that works. :-) (Assuming this is a > problem for you.) > > Regards, > George.Hey George - Thanks for the quick response. I''d like intercept all method calls to my models accessing an attribute in order to implement an attribute level authorization scheme - similar to the J2EE analog which is a pain but works (specified in ejb-jar.xml). I think I found a way to configure rails to not generate the ENTIRE method list lazily - but the implication is that I''ll loose on performance: config.active_record.generate_read_methods = false (instead of the default value of true) Anyone got any Ideas? Regards, Aakash -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
George Ogata
2007-Feb-11 09:45 UTC
Re: method_missing in a AR child only catching 1 of several
On 2/11/07, AC CE <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > George Ogata wrote: > . > . > > I''m not sure what you''re trying to do, but if you explain it, someone > > might be able to find something that works. :-) (Assuming this is a > > problem for you.) > > > > Regards, > > George. > > Hey George - Thanks for the quick response. > > I''d like intercept all method calls to my models accessing an attribute > in order to implement an attribute level authorization scheme - similar > to the J2EE analog which is a pain but works (specified in ejb-jar.xml). > > I think I found a way to configure rails to not generate the ENTIRE > method list lazily - but the implication is that I''ll loose on > performance: > > config.active_record.generate_read_methods = false (instead of the > default value of true) > > Anyone got any Ideas?Have you looked around at the existing model-level authentication plugins? I think some do attribute-level authorization. e.g., [1]. If that doesn''t fly for you, I''m not sure what the best way to do this is. Once you''ve generated the read methods, they''re available via ModelName.read_methods. Perhaps you can override these. I don''t think that''s particularly watertight, though. #read_attribute, for example seems to pull things directly out of the @attributes hash inside the active record instances directly rather than going through the read methods. Perhaps you could hook into the #[] method on this hash, but that''s getting pretty nasty! class ActiveRecord::Base def initialize_with_authorization_check(*args) initialize_without_authorization_check(*args) do |*args| class << @attributes def [](name) # ... authorization check ... super end def []=(name, value) # ... authorization check ... super end end yield(*args) if block_given? end end alias initialize_without_authorization_check initialize alias initialize initialize_with_authorization_check end (Totally untested.) [1] http://perens.com/FreeSoftware/ModelSecurity/ George. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---