I am trying to monkey-patch the ActiveRecord::Base class to incorporate a generic search class method so that it can be used by all model classes which need this functionality. Since model classes directly inherit from ActiveRecord::Base and unlike controllers and helpers, do not have an ancestor class defined, I think I am forced to open the ActiveRecord::Base class and patch it? May be I am wrong. Anyway, here is my code in the active_record_extensions.rb file that I created in the RAILS_ROOT/lib directory: module ActiveRecord class Base def self.search(search, current_page) if search.blank? paginate(:all, :page => current_page || 1, :per_page => 5) else paginate(:all, :conditions => ["name LIKE ?", "%#{search}%"], :order => ''name'', :page => current_page || 1, :per_page => 5) end end end end Note that paginate method comes from the will_paginate plugin installed in vendor/plugins directory. This does not work. My program is having trouble with the paginate method from will_paginate plugin being called in the code shown above? This seems to be a load_path issue? One way to solve this is to install will_paginate as a gem and then require it before calling paginate? But is there a way to make with work as a plugin as I have it currently for creating this generic routine? Thanks for your time in advance. Bharat -- 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 -~----------~----~----~----~------~----~------~--~---
On Mar 23, 2009, at 5:09 PM, Bharat Ruparel wrote:> > I am trying to monkey-patch the ActiveRecord::Base class to > incorporate > a generic search class method so that it can be used by all model > classes which need this functionality. Since model classes directly > inherit from ActiveRecord::Base and unlike controllers and helpers, do > not have an ancestor class defined, I think I am forced to open the > ActiveRecord::Base class and patch it? May be I am wrong. Anyway, > hereWhy not create your method as a module and then include it into the classes you need it? Look at any of the plugins out there that are of the "acts_as_xxxx" variety which add methods to the model they are called from... just follow those examples and you shouldn''t need to directly modify AR::Base like this.> is my code in the active_record_extensions.rb file that I created in > the > RAILS_ROOT/lib directory: > > module ActiveRecord > > class Base > def self.search(search, current_page) > if search.blank? > paginate(:all, :page => current_page || 1, :per_page => 5) > else > paginate(:all, :conditions => ["name LIKE ?", "%#{search}%"], > :order => ''name'', > :page => current_page || 1, :per_page => 5) > end > end > end > > end > > Note that paginate method comes from the will_paginate plugin > installed > in vendor/plugins directory. > > This does not work. My program is having trouble with the paginate > method from will_paginate plugin being called in the code shown above? > > This seems to be a load_path issue? One way to solve this is to > install > will_paginate as a gem and then require it before calling paginate? > But > is there a way to make with work as a plugin as I have it currently > for > creating this generic routine? > > Thanks for your time in advance. > > Bharat > -- > 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 -~----------~----~----~----~------~----~------~--~---
Thanks Phillip. I will follow your advice and see if I can do it. -- 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 -~----------~----~----~----~------~----~------~--~---
> Why not create your method as a module and then include it into the > classes you need it? Look at any of the plugins out there that are of > the "acts_as_xxxx" variety which add methods to the model they are > called from... just follow those examples and you shouldn''t need to > directly modify AR::Base like this.Further, adding a method to a class is a perfectly reasonable solution, and is not "monkey patching". That''s when you change a preexisting method, simply because it offered no hook for you to override. In order from sublime to icky... - delegate to the behavior you need - include/extend the behavior - inherit the behavior - add the behavior to your base class - trigger the behavior with an ''if'' statement - monkey-patch the behavior into a closed class Yes, folks, the lowly ''if'' statement is the second-worst option in Object Oriented programming. Use it with extreme caution! --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Could not get to it yesterday due to other work. Am still struggling with it. There is something basic that I do not understand. I have looked at acts_as plugins (list and tree for instance). I am afraid that is not going to help me. Here is the thing that I do not get: 1. The Rails lib directory contains reusable code that can be used anywhere in that particular Rails application. Following that basic concept, I created a file called active_records_extensions.rb in it which has the following slightly modified code from the previous posting: module ActiveRecord class Base class << self def search(search, current_page) if search.blank? WillPaginate::Finder::paginate(:all, :page => current_page || 1, :per_page => 5) else WillPaginate::Finder::paginate(:all, :conditions => ["name LIKE ?", "%#{search}%"], :order => ''name'', :page => current_page || 1, :per_page => 5) end end end end end Now search is supposed to be a class method since it is called from the index method of a controller like this: def index @pizzas = Pizza.search(params[:search], params[:page]) end That is why I am defining the search method as a class method for ActiveRecord::Base class as shown above. I have done this sort of thing many times before without any problems. The twist this time is that the "Search" method is calling the paginate class method of will_paginate plugin. First, I tried requiring the will_paginate class method, but that did not work. Next, I tried giving the full path for the paginate class method as shown above in the code. Still, I get the same error. Here is the stack trace snippet. NoMethodError (undefined method `search'' for #<Class:0xb7143b6c>): /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/base.rb:1672:in `method_missing_without_paginate'' /vendor/plugins/will_paginate/lib/will_paginate/finder.rb:170:in `method_missing'' /app/controllers/pizzas_controller.rb:17:in `index'' /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_controller/base.rb:1166:in `send'' /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_controller/base.rb:1166:in `perform_action_without_filters'' /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_controller/filters.rb:579:in `call_filters'' /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_controller/filters.rb:572:in `perform_action_without_benchmark'' /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'' /usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'' I am hoping someone can help me understand what is it that I am missing. I am doing this project to further my knowledge about designing reusable code in Rails and there is something fundamental that I am not able to grasp. As always, thanks for your time. Bharat -- 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 -~----------~----~----~----~------~----~------~--~---
I have reduced the problem down to the following: whatever method I define in the lib directory under active_record_extensions.rb, is not being loaded by rails. This has worked perfectly for me in a large Rails 2.1.0 application. So here is the problem: RAILS_ROOT/lib/active_record_extensions.rb: module ActiveRecord class Base class << self def hello puts "Hello from active record" end end end end I start the server. I load Rails Console and try to invoke hello method on any model class. I get exactly the same error as shown below on Pizza class for example: bruparel@bcr-d810:~/exp/pizzeria-3$ ruby ./script/console Loading development environment (Rails 2.1.2)>> Pizza.helloNoMethodError: undefined method `hello'' for #<Class:0xb784607c> from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/base.rb:1672:in `method_missing_without_paginate'' from /home/bruparel/exp/pizzeria-3/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:170:in `method_missing'' from (irb):1>> CrustType.helloNoMethodError: undefined method `hello'' for #<Class:0xb72087dc> from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/base.rb:1672:in `method_missing_without_paginate'' from /home/bruparel/exp/pizzeria-3/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:170:in `method_missing'' from (irb):2 Does anyone know what is going on? -- 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 -~----------~----~----~----~------~----~------~--~---
On Mar 25, 3:04 pm, Bharat Ruparel <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Does anyone know what is going on?That file''s not going to magically load itself. you need to require it (eg from an initializer in config/initializers)> -- > Posted viahttp://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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Wed, Mar 25, 2009 at 10:04 AM, Bharat Ruparel <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > I have reduced the problem down to the following: whatever method I > define in the lib directory under active_record_extensions.rb, is not > being loaded by rails.I found the same problem when upgrading an app to 2.3.2 yesterday. I fixed it using Dir.glob( "#{ RAILS_ROOT }/lib/*.rb" ).each { |f| require f } in config/environment.rb. -- Greg Donald http://destiney.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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thank you Fred and Greg. You both are right. I had a similar load configuration block as Greg shows here in my environment file in the application where it worked fine and had forgotten all about it. For this little application, I put the following statement at the end of config/environment.rb: require "#{RAILS_ROOT}/lib/active_record_extensions.rb" And everything works fine. I was under the impression that everything in the lib directory gets loaded automatically which is apparently an incorrect assumption. Question is: what is the significance of the "lib" directory then in a Rails environment? If it just gets added in the Rails load path and nothing else then it leaves me scratching my head. Either don''t put in the load path automatcially or if we do then load whatever is in there automatically too. Don''t you think Rails is at odds with itself here? Bharat -- 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 -~----------~----~----~----~------~----~------~--~---
On 25 Mar 2009, at 16:11, Bharat Ruparel wrote:> > Question is: what is the significance of the "lib" directory then in a > Rails environment? If it just gets added in the Rails load path and > nothing else then it leaves me scratching my head. Either don''t put > in > the load path automatcially or if we do then load whatever is in there > automatically too. Don''t you think Rails is at odds with itself here? >Except for the production mode stuff, nothing gets loaded automatically (the const_missing hook can make it seem that way though. The difference with a file like the one you had is that there isn''t a top level constant one would naturally refer to) Fred> Bharat > -- > 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 -~----------~----~----~----~------~----~------~--~---
"The difference with a file like the one you had is that there isn''t a top level constant one would naturally refer to)" Thanks for the explanation Fred. But I don''t understand this. Can you give me a simple example? Bharat -- 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 -~----------~----~----~----~------~----~------~--~---
On Mar 25, 8:22 pm, Bharat Ruparel <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> "The difference with a file like the one you had is that there > isn''t a top level constant one would naturally refer to)" > > Thanks for the explanation Fred. But I don''t understand this. Can you > give me a simple example? >If what you were doing was providing a class that other bits of your app use then you might have discombobulator.rb which defined Discombobulator, and bits of your app might do Discombobulator.discombobulate. When they did that and if the file had not been loaded yet then this would trigger const_missing (since there is no Discombobulator constant). Rails'' response to this is to search for a file called discombobulator.rb and try and load it. However when you have a file in lib that is just adding a method to some existing class or overriding something then there is no constant like Discombobulator that will trigger loading of the file. Fred --~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
"However when you have a file in lib that is just adding a method to some existing class or overriding something then there is no constant like Discombobulator that will trigger loading of the file." Got it. Thanks. -- 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 -~----------~----~----~----~------~----~------~--~---