I''m trying to generate a "page slug" i.e. a url sanitized id from some text in my model that I want to be saved into the database and I''m not seeing how I can do it. The closest I''ve come to getting this to work has been... class Page < ActiveRecord::Base attr :name before_save :generate_slug def generate_slug self.slug = self.name.gsub /\W+/, ''-'' end end ...but this is unsatisfactory as I would like to have the slug generated from the name without having to save to the database. anyone have an idea of the proper Ruby way? Ideally I''d like to be able to do the following... >> p = Page.new :name => ''My test page'' => #<Page:0x271ff38 @attributes={"slug"=>"My-test-page", "name"=>"My test page"}, @new_record=true> >> p.slug => "My-test-page" >> p.name = ''Foo Bar'' => "Foo Bar" >> p.slug => "Foo-Bar" Ideally it seems that Page#slug should generate the slug based on the name every time it is accessed like def slug self.name.gsub /\W+/, ''-'' end but it seems when I save my model to the db Page#slug does not get called and so the slug does not get saved to the db (and therfore remains ''null''). Any ideas? TIA -- Craig Beck http://www.luckybonza.com AIM: kreiggers
In reply to my own post...> I''m trying to generate a "page slug" i.e. a url sanitized id from > some text in my model that I want to be saved into the database and > I''m not seeing how I can do it. > > The closest I''ve come to getting this to work has been... > > class Page < ActiveRecord::Base > attr :name > > before_save :generate_slug > > def generate_slug > self.slug = self.name.gsub /\W+/, ''-'' > end > end > > ...but this is unsatisfactory as I would like to have the slug > generated from the name without having to save to the database.a couple of other constriants... 1. the slug should be write only as it is calculated from the Page#name so should only change when the name does 2. the slug has to be stored in the db as this is how I''m going to retrieve the record> anyone have an idea of the proper Ruby way? Ideally I''d like to be > able to do the following... > > >> p = Page.new :name => ''My test page'' > => #<Page:0x271ff38 @attributes={"slug"=>"My-test-page", > "name"=>"My test page"}, @new_record=true> > >> p.slug > => "My-test-page" > >> p.name = ''Foo Bar'' > => "Foo Bar" > >> p.slug > => "Foo-Bar" > > Ideally it seems that Page#slug should generate the slug based on > the name every time it is accessed like > > def slug > self.name.gsub /\W+/, ''-'' > end > > but it seems when I save my model to the db Page#slug does not get > called and so the slug does not get saved to the db (and therfore > remains ''null''). Any ideas? TIA-- Craig Beck http://www.luckybonza.com AIM: kreiggers
Craig Beck wrote:> I''m trying to generate a "page slug" i.e. a url sanitized id from > some text in my model that I want to be saved into the database and > I''m not seeing how I can do it. > > The closest I''ve come to getting this to work has been... > > class Page < ActiveRecord::Base > attr :name > > before_save :generate_slug > > def generate_slug > self.slug = self.name.gsub /\W+/, ''-'' > end > end > > ...but this is unsatisfactory as I would like to have the slug > generated from the name without having to save to the database. > > anyone have an idea of the proper Ruby way? Ideally I''d like to be > able to do the following... > > >> p = Page.new :name => ''My test page'' > => #<Page:0x271ff38 @attributes={"slug"=>"My-test-page", "name"=>"My > test page"}, @new_record=true> > >> p.slug > => "My-test-page" > >> p.name = ''Foo Bar'' > => "Foo Bar" > >> p.slug > => "Foo-Bar" > > Ideally it seems that Page#slug should generate the slug based on the > name every time it is accessed like > > def slug > self.name.gsub /\W+/, ''-'' > end > > but it seems when I save my model to the db Page#slug does not get > called and so the slug does not get saved to the db (and therfore > remains ''null''). Any ideas? TIACombine your before_save callback with lazy initialization in the accessor. before_save :slug def slug @slug ||= self.name.gsub /\W+/, ''-'' end def name=(name) attributes[:name] = name slug = nil end By the way, here''s the snippet I use for slugs. It''s a bit more forgiving of odd user input than yours. (based on Rick Olson''s in Mephisto, then tweaked all to heck) title.downcase.gsub(/[''"]/, '''').gsub(/\W+/, '' '').squeeze('' '').strip.gsub(/ /, ''-'') -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.