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