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 B.’
=> “Foo B.”
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 B.
http://www.luckybonza.com
AIM: kreiggers
In reply to my own post…
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…
- the slug should be write only as it is calculated from the
Page#name so should only change when the name does
- the slug has to be stored in the db as this is how I’m going to
retrieve the record
p.slug
called and so the slug does not get saved to the db (and therfore
remains ‘null’). Any ideas? TIA
–
Craig B.
http://www.luckybonza.com
AIM: kreiggers
Craig B. 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 B.’
=> “Foo B.”
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
Combine 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 O.'s in
Mephisto, then tweaked all to heck)
title.downcase.gsub(/[’"]/, ‘’).gsub(/\W+/, ’ ‘).squeeze(’
').strip.gsub(/ /, ‘-’)
–
Josh S.
http://blog.hasmanythrough.com