Topic: Regular Expressions for Clean URLS

I am using permalinks for quite a few of my applications and am not quite getting my REGEXPs right

My aim is to replace spaces with a hyphen "-" character and to ignore any characters that are not alphanumeric.

def before_create
     @attributes['permalink'] = title.downcase.gsub(/\s+/, '-').gsub(/[^a-zA-Z0-9_]+/, '')
   end

This seems to get the alpha-numeric part right, but there are no dashes and my words get sandwiched together.

Another issue I have is that this method is sitting in my model.rb file and I will need it to be used in many places. I know that application.rb is the place for all your controllers to inherit their behavior, but where do I go for models?

Re: Regular Expressions for Clean URLS

The problem is you first convert spaces to dashes, but then you strip the dashes in the second gsub. You need to exclude those as well:

title.downcase.gsub(/\s+/, '-').gsub(/[^a-zA-Z0-9_-]+/, '')

You could put this in a string method:

class String
  def make_permalink
    downcase.gsub(/\s+/, '-').gsub(/[^a-zA-Z0-9_-]+/, '')
  end
end

Then you just call that in your model:

def before_create
  self.permalink = title.make_permalink
end

Railscasts - Free Ruby on Rails Screencasts

Re: Regular Expressions for Clean URLS

The question is, where do I put that string method?

I still dont grasp how to access the parent class of all my models

Re: Regular Expressions for Clean URLS

I recommend putting little utility bits of code like this in a separate file in the lib directory. You may need to "require" it in environment.rb if it doesn't load it automatically.

What do you mean by accessing the parent class of all your models. Do you mean ActiveRecord::Base? What are you trying to do with it?

Railscasts - Free Ruby on Rails Screencasts

Re: Regular Expressions for Clean URLS

I was just curious.. i know that controllers inherit from application_controller but there is no concrete file like this for models. I will try slapping it in my lib, first time I ever use this folder actually..its about time!

Re: Regular Expressions for Clean URLS

Hmm, I get a method missing error when I include in my environment like so:

require File.join(File.dirname(__FILE__), 'boot')
require 'lib/string_helper.rb'

is that correct place for it?

Re: Regular Expressions for Clean URLS

Have you looked at the application.rb file in the controllers directory, generated when you created your app?  There's a comment which says

# Likewise, all the methods added will be available for all controllers.

If you have functions you want all controllers to be able to use, you can also add them to this class.

BrewControl.com - Brewery and Brewpub management powered by RoR

Re: Regular Expressions for Clean URLS

bkrahmer,

I love and use application controller whenever possible.. I was looking for the equivalent for Rails models. Beginning to think it wouldnt be such a bad idea. Our controllers and views have master files to inherit from, why not the models too?

Re: Regular Expressions for Clean URLS

Just do this to require it:

require 'string_helper'

If you need to share methods with models, I recommend placing the methods in a module and including it into the models that will need it:

module Product
  def dollars
    cents / 100.0
  end
end

class Book < ActiveRecord::Base
  include Product
end

class Video < ActiveRecord::Base
  include Product
end

Railscasts - Free Ruby on Rails Screencasts

Re: Regular Expressions for Clean URLS

Still no worky.

I placed my module code into the string_helper file

module Permalinks
  def make_permalink
    downcase.gsub(/\s+/, '-').gsub(/[^a-zA-Z0-9_-]+/, '')
  end
end

and required it in my environment and also included in my model.. all I get is

uninitialized constant Term::Permalinks

argh

Re: Regular Expressions for Clean URLS

That was for if you need to share code across models which doesn't belong anywhere else. In this case just put it in the string class since I think it goes there:

class String
  def make_permalink
    downcase.gsub(/\s+/, '-').gsub(/[^a-zA-Z0-9_-]+/, '')
  end
end

Save it into a file in the "lib" directory, then require it in environment.rb:

require 'string_helper' # will load lib/string_helper.rb

Is that working?

Railscasts - Free Ruby on Rails Screencasts

Re: Regular Expressions for Clean URLS

Sorry, I didn't read the post close enough...

BrewControl.com - Brewery and Brewpub management powered by RoR

Re: Regular Expressions for Clean URLS

Still no love from my helper sad

I followed your instructions to the letter, my environment now looks like this:


RAILS_GEM_VERSION = '1.2.3' unless defined? RAILS_GEM_VERSION

# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
require 'string_helper'

Rails::Initializer.run do |config|


and get this error

undefined method `make_permalink' for "title":String

Last edited by pimpmaster (2007-04-04 23:56:04)

Re: Regular Expressions for Clean URLS

Interesting. Try moving the require statement to the bottom of environment.rb.

I'm not sure what the problem could be then. Try loading script/console and calling make_permalink on a string there. Also try doing the require statement there and see if it says anything.

Railscasts - Free Ruby on Rails Screencasts

Re: Regular Expressions for Clean URLS

Moving that require statement to the bottom of environment file did the trick.

Rails is a picky mistress, eh?

Re: Regular Expressions for Clean URLS

Well its a good thing I test out my links.. apparently some  of my entries that start with a "." are conflicting with my other entries.

What I need is a regexp that will take entries that begin with a period and then change that period to "dot-"

I been scouring the net but so far no luck.

Note to self: buy the damn pickaxe book already!

Re: Regular Expressions for Clean URLS

.sub(/^\./, 'dot-')

Last edited by bkrahmer (2007-04-10 20:42:15)

BrewControl.com - Brewery and Brewpub management powered by RoR

Re: Regular Expressions for Clean URLS

Hmm, for some reason it's not working, maybe too many gsubs??

downcase.gsub(/^\./, 'dot-').gsub(/\s+/, '-').gsub(/[^a-zA-Z0-9_-]+/, '')

Edit: I figured it out on me own.. Regex is not as hard as I thought!

downcase.sub(/^\./, 'dot-').gsub(/\W|\s+/, '-').gsub(/[^a-zA-Z0-9_-]+/, '')

If any of you are intimidated by regular expressions like I was, check out this awesome PDF tutorial

Last edited by pimpmaster (2007-04-11 05:33:40)

Re: Regular Expressions for Clean URLS

Here is a chellenging regex. The find part is easy, I am just not sure how to swap out the desired values. Basically, I need to change my textile URLs from these:

:/1/123
:/a/a-term

to these:

:/terms/numbers/123
:/terms/a/a-term
* repeat for all alphabet

I know how to do it on a case by case basis, but i know that 27 gsubs is not a good idea. This is as far as I have gotten:

gsub(/(:\/[a-z])+/, ':/terms/([a-z])').gsub(/(:\/1)+/, ':/terms/numbers')

The numbers bit works perfectly, I just don't know how to preserve values for the letter ranges.

Last edited by pimpmaster (2007-04-11 10:24:14)

Re: Regular Expressions for Clean URLS

Hey, I'm getting the hang of this!

gsub(/:\/([a-z])\/+/, ':/terms/\1/').gsub(/(:\/1\/)+/, ':/terms/numbers/')

Here is a sweet lil resource for gsub in Ruby

Last edited by pimpmaster (2007-04-11 11:12:07)