I have written two helper methods that I wish to have these available in all of my models. I have placed them in a module called prep_index_string.rb which looks like this: module PrepIndexString # This method prepares descriptive strings that are used as # indices for lookups. The keycase strips method leading and # trailing spaces, squeezes out extra whitespace between words, # and then downshifts all. # # Do not use ! methods as they return nil under certain circumstances # # If the attribute passed does not respond to the to_s message then throw # an error. There is nothing useful we can do here. def keycase(value) value = value.to_s.strip.squeeze(" ").downcase end # This method simply upshifts the first character of every element # separated by a word boundary in a string. def titlecase(value) value = value_to_s.gsub(/\b\w/){$&.upcase} end end How and where is the best way to mixin these two methods for every model (and possibly every view and controller as well) in a particular rails project? I initially added these to application_helper.rb but have since discovered that this is completely ignored by models. I tried requiring "prep_index_string" and including/extending PrepIndexString at the top of the model files but I nonetheless threw undefined method errors on both methods whatever I tried. It almost seems to me as if I should subclass String and mix them in there but how should I do this for just one Rails project? -- 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 -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> I have written two helper methods that I wish to have these available in > all of my models. I have placed them in a module called > prep_index_string.rb which looks like this: > > module PrepIndexString > > # This method prepares descriptive strings that are used as > # indices for lookups. The keycase strips method leading and > # trailing spaces, squeezes out extra whitespace between words, > # and then downshifts all. > # > # Do not use ! methods as they return nil under certain circumstances > # > # If the attribute passed does not respond to the to_s message then > throw > # an error. There is nothing useful we can do here. > def keycase(value) > value = value.to_s.strip.squeeze(" ").downcase > end > > # This method simply upshifts the first character of every element > # separated by a word boundary in a string. > def titlecase(value) > value = value_to_s.gsub(/\b\w/){$&.upcase} > end > > end > > How and where is the best way to mixin these two methods for every model > (and possibly every view and controller as well) in a particular rails > project? I initially added these to application_helper.rb but have > since discovered that this is completely ignored by models. I tried > requiring "prep_index_string" and including/extending PrepIndexString at > the top of the model files but I nonetheless threw undefined method > errors on both methods whatever I tried. > > It almost seems to me as if I should subclass String and mix them in > there but how should I do this for just one Rails project?I followed this blog post for mixing in Class level methods "http://redcorundum.blogspot.com/2006/06/mixing-in-class-methods.html" but in your case, couldn''t you just drop your module in "lib" and "include YourModule" in your model classes? that''s what I would try --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Andy Koch wrote:> > I followed this blog post for mixing in Class level methods > "http://redcorundum.blogspot.com/2006/06/mixing-in-class-methods.html" >The blog you were looking for was not found. Thanks. I will try moving the file as you suggest. -- 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 -~----------~----~----~----~------~----~------~--~---
2008/3/13, James Byrne <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>:> > I have written two helper methods that I wish to have these available in > all of my models. I have placed them in a module called > prep_index_string.rb which looks like this: > [...] > How and where is the best way to mixin these two methods for every model > (and possibly every view and controller as well) in a particular rails > project? I initially added these to application_helper.rb but have > since discovered that this is completely ignored by models. I tried > requiring "prep_index_string" and including/extending PrepIndexString at > the top of the model files but I nonetheless threw undefined method > errors on both methods whatever I tried.Here''s the relevant chapter in the old Pickaxe: http://ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html Put prep_index_string.rb in the lib/ directory. Then include the module in all the classes you want to use the methods: require "prep_index_string" class SomeModelOrController include PrepIndexString # blah blah end This makes the methods available at the _instance_ level. If you want to have them at the class level too, add the line "extend PrepIndexString" near the include line. If you don''t wan''t to manually include it in every class you can go the hardcore route and extend ActionController::Base and ActiveRecord::Base. Put this in lib/prep_index_string_extension.rb: require "prep_index_string" class ActiveRecord::Base include PrepIndexString extend PrepIndexString end class ActionController::Base include PrepIndexString extend PrepIndexString end and require "prep_index_string_extension" in environment.rb. And make all the methods in PrepIndexString private. You might also consider putting it in a plugin. Stefan --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
another solution : http://weblog.jamisbuck.org/2007/1/17/concerns-in-activerecord In short : place your model modules in a dedicated directory (../concerns) that you add to the load path. 1: file config/environement.rb: ----------------- ... # tell Rails how to find your modules : config.load_paths += %W( #{RAILS_ROOT}/app/models/concerns ) ... 2: one such shared module : ----------------- in app/models/concerns/super_powers.rb module SuperPowers .. end 3: and finally, in your model ----------------- class People << AR include SuperPowers ... end Alain --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Andy Koch wrote:> > but in your case, couldn''t you just drop your module in "lib" and > "include YourModule" in your model classes? > > that''s what I would try]$ ll lib/*rb -rw-rw-r-- 1 byrnejb byrnejb 728 Mar 13 14:43 lib/prep_index_string.rb $ cat lib//prep_index_string.rb module PrepIndexString # This method prepares descriptive strings that are used as # indices for lookups. The keycase strips method leading and # trailing spaces, squeezes out extra whitespace between words, # and downshifts all. # # Do not use ! methods as they return nil under certain circumstances # # If the attribute passed does not respond to the to_s message then throw # an error. There is nothing useful we can do here. def keycase(value) value = value.to_s.strip.squeeze(" ").downcase end # This method simply upshifts the first character of every element # separated by a word boundary in a string. def titlecase(value) value = value_to_s.gsub(/\b\w/){$&.upcase} end end $ cat app/models/entity.rb require ''prep_index_string'' class Entity < ActiveRecord::Base include PrepIndexString has_one :client before_save :set_index_values validates_presence_of :entity_name validates_presence_of :entity_legal_name validates_presence_of :entity_legal_form def set_index_values self[:entity_name] = self.entity_name.keycase end end NoMethodError in ClientsController#create undefined method `keycase'' for "A test name":String I do not know what I am doing wrong. -- 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 -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> I do not know what I am doing wrong.Even if I put the keycase method into the entity model I still get the same error!? #require ''prep_index_string'' class Entity < ActiveRecord::Base include PrepIndexString #has_one :person has_one :client #has_one :vendor # #has_many :channels #has_many :contacts #has_many :identities #has_many :job_parties #has_many :locations # before_save :set_index_values validates_presence_of :entity_name validates_presence_of :entity_legal_name validates_presence_of :entity_legal_form def set_index_values self[:entity_name] = self.entity_name.keycase end def keycase(value) value = value.to_s.strip.squeeze(" ").downcase end end What is Rails doing? -- 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 -~----------~----~----~----~------~----~------~--~---
James Byrne wrote: In console this works: class Entity < ActiveRecord::Base before_save :keycase def keycase self.entity_name = self.entity_name.to_s.strip.squeeze(" ").downcase end end and this works: class Entity < ActiveRecord::Base before_save :set_index_values def set_index_values #self[:entity_name] = self.entity_name.keycase keycase end def keycase self.entity_name = self.entity_name.to_s.strip.squeeze(" ").downcase end But his does not: class Entity < ActiveRecord::Base before_save :set_index_values def set_index_values self.entity_name = self.entity_name.keycase end def keycase( value ) value.to_s.strip.squeeze(" ").downcase end end $ ruby script/console Loading development environment (Rails 2.0.2)>> load "entity.rb"=> ["Entity"]>> en = Entity.new=> #<Entity id: nil, entity_name: nil, entity_legal_name: nil, entity_legal_form: nil, created_at: nil, updated_at: nil>>> en.entity_name = "UPERAND"=> "UPERAND">> en.entity_legal_name = "UperAnd Ltd."=> "UperAnd Ltd.">> en.entity_legal_form = "PERS"=> "PERS">> en.saveNoMethodError: undefined method `keycase'' for "UPERAND":String from /home/byrnejb/Software/Development/Projects/invert/app/models/entity.rb:27:in `set_index_values'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:307:in `send'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:307:in `callback'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:304:in `each'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:304:in `callback'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:212:in `create_or_update'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1972:in `save_without_validation'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/validations.rb:934:in `save_without_transactions'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:108:in `save'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:66:in `transaction'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:80:in `transaction'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:100:in `transaction'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:108:in `save'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:120:in `rollback_active_record_state!'' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:108:in `save'' from (irb):6>>Can anytone tell me why? -- 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 -~----------~----~----~----~------~----~------~--~---
Hi -- On Thu, 13 Mar 2008, James Byrne wrote:> > James Byrne wrote: > > In console this works: > > class Entity < ActiveRecord::Base > > before_save :keycase > > def keycase > self.entity_name = self.entity_name.to_s.strip.squeeze(" ").downcase > end > end > > and this works: > > class Entity < ActiveRecord::Base > > before_save :set_index_values > > def set_index_values > #self[:entity_name] = self.entity_name.keycase > keycase > end > > def keycase > self.entity_name = self.entity_name.to_s.strip.squeeze(" ").downcase > end > > But his does not: > > class Entity < ActiveRecord::Base > > before_save :set_index_values > > def set_index_values > self.entity_name = self.entity_name.keycase > end > > def keycase( value ) > value.to_s.strip.squeeze(" ").downcase > end > end[...]> > Can anytone tell me why?self.entity_name is a string. You''re calling keycase on that string, but strings don''t have a keycase method. You''d have to do: self.entity_name = keycase(self.entity_name) if you''re writing keycase to take an argument. David -- Upcoming Rails training from David A. Black and Ruby Power and Light: ADVANCING WITH RAILS, April 14-17 2008, New York City CORE RAILS, June 24-27 2008, London (Skills Matter) See http://www.rubypal.com for details. Berlin dates coming soon! --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
David A. Black wrote:> > self.entity_name is a string. You''re calling keycase on that string, > but strings don''t have a keycase method. > > You''d have to do: > > self.entity_name = keycase(self.entity_name) > > if you''re writing keycase to take an argument. > >Thank you. This explains why placing this in a module did not work either. Now my question becomes: where would I subclass String to add these two methods for a specific rails project? -- 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 -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> Now my question becomes: where would I subclass String to add these two > methods for a specific rails project?I need to clarify this. What I want to accomplish is to add these two methods to the String class, but only for a particular project. What is the recommended manner to accomplish this? I speculate that somewhere in the load path I will need to create a class called String that descends from String and adds these two methods. The question is where? Class String def keycase(value) value = value.to_s.strip.squeeze(" ").downcase end def titlecase(value) value = value_to_s.downcase.gsub(/\b\w/){$&.upcase} end end -- 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 -~----------~----~----~----~------~----~------~--~---
Hi -- On Thu, 13 Mar 2008, James Byrne wrote:> > James Byrne wrote: > >> Now my question becomes: where would I subclass String to add these two >> methods for a specific rails project? > > I need to clarify this. What I want to accomplish is to add these two > methods to the String class, but only for a particular project. What is > the recommended manner to accomplish this? I speculate that somewhere > in the load path I will need to create a class called String that > descends from String and adds these two methods. The question is where? > > Class String > > def keycase(value) > value = value.to_s.strip.squeeze(" ").downcase > end > > def titlecase(value) > value = value_to_s.downcase.gsub(/\b\w/){$&.upcase} > end > > endIf you want to add methods to the String class, you don''t need to create a class; you just need to re-open the existing String class (which is what you''ve done above, except you''ve capitalized "class" :-) Furthermore, if you''re defining the methods on the class, you don''t want them to take an argument: class String def keycase strip.squeeze(" ").downcase end end Typically you would put a modification like this in the lib directory, and require the file at runtime, or you''d put it in a file in the config/initializers directory, in which case it would be read and loaded automatically. Note that Rails already adds titlecase to String. David -- Upcoming Rails training from David A. Black and Ruby Power and Light: ADVANCING WITH RAILS, April 14-17 2008, New York City CORE RAILS, June 24-27 2008, London (Skills Matter) See http://www.rubypal.com for details. Berlin dates coming soon! --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> James Byrne wrote: > >> Now my question becomes: where would I subclass String to add these two >> methods for a specific rails project? >or should I do something like this instead? String.class_eval do def keycase self.to_s.strip.squeeze(" ").downcase end def titlecase self.to_s.downcase.gsub(/\b\w/){$&.upcase} end end But again, where do I put this? -- 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 -~----------~----~----~----~------~----~------~--~---
David A. Black wrote:> > Note that Rails already adds titlecase to String.Which demonstrates yet again that if one wants to find out what is already available, try to do it yourself first. Sigh. 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 -~----------~----~----~----~------~----~------~--~---
David A. Black wrote:> or you''d put it in a file in the config/initializers directory, > in which case it would be read and loaded automatically.Works perfectly. Thank you again. -- 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 -~----------~----~----~----~------~----~------~--~---