User Permalink in Rails ???

Hey guys,

How do we create Permalinks for users in a Rails application ??? By Permalink a mean the name of the user in the URL like so: example.com/username... Or like twitter and everyone does it ex: twitter.com/username...

I checked everywhere for that and didnt find a relevant answer... I think it has something to do with overriding the to_param method in the User model... but according to this screencast from Ryan Bates, #63 Model Name in URL - RailsCasts, it's very risky to remove the id from the url...

Is there a way to do it ??? I suppose there is...

Thx for your help...

Louis-Pierre

You could just do that for the show method. Depending on your situation. If you were to pass the username in the query string just use a method like this:

def show @user = User.find_by_username(params[:id]) end

-Chris

Well, I haven't watched the screencast, but can't really imagine how "harmful" that could be.

The first thing you would need to do is use the permalink_fu plugin -> http://github.com/technoweenie/permalink_fu/tree/master

And then you could override the "find" method in your model to a finder like this one:

    def find( *args )

      if args.first.kind_of?( String ) and !args.first.kind_of?( Symbol ) and (args.first !~ /^[0-9]/ || args.first.include?('-'))         if args.size == 1           super :first, :conditions => { permalink_field => args.first }         else           with_scope :find => { :conditions => { permalink_field => args.first } } do               args[ 0 ] = :first               super( *args )           end         end       else         super( *args )       end

    end

What would assure that if a number is passed, it would use the good old finder, but if it's not a number, it will try to find using the permalink_field. This has solved my needs, maybe it can solve yours too.

Ok... I'll try that then... Thx a lot for helping...

Louis-Pierre

You could just do that for the show method. Depending on your situation. If you were to pass the username in the query string just use a method like this:

def show @user = User.find_by_username(params[:id]) end

-Chris

I think this is the right approach

take a look at the rails docs on to_param.

So the right solution is

map.resources :users

class User   def to_param     self.username   end end

class UsersControllers   def show      @user = User.find_by_username(params[:id])   end

  def something_that_redirects      redirect_to users_path(@user)   end end

Should suffice, and is much better practice than overwriting the "find" method.

Enjoy.

Matthew Rudy

LOL There's no reason to use to_param. It's just a convention to pass the id through the URL. It's type is not enforced.

# expects /users/15 def edit   @user = User.find(params[:id]) end

# expects /users/bphogan def show   @user = User.find_by_username(params[:id]) end

The only thing to watch out for is that find throws a RecordNotFound exception when there is no record found, which will display a 404 in production, and find_by_username returns nil, so you'll wanna handle that.

But there's no need to do anything funny with to_params or routing or anything like that.

And if you DO use to_param and do something like this:

def to_param    "#{id}-#{name}" end

And then go to the URL such as /users/15-Radar

In that show action you can then do:

User.find(params[:id])

still, and get the user. This is because the find calls to_i on the
string that is passed into it, so it is equivalent to doing
User.find(15).

Brian Hogan wrote:

LOL There's no reason to use to_param. It's just a convention to pass the id through the URL. It's type is not enforced.

# expects /users/15 def edit   @user = User.find(params[:id]) end

# expects /users/bphogan def show   @user = User.find_by_username(params[:id]) end

The only thing to watch out for is that find throws a RecordNotFound exception when there is no record found, which will display a 404 in production, and find_by_username returns nil, so you'll wanna handle that.

But there's no need to do anything funny with to_params or routing or anything like that.

Thx a lot but I really do want to get rid of the /user before "username" so my url looks like this: http://mydomain.com/username… like i said before... http://twitter.com/gigaom for instance... How do i get rid of "user/" in the url ???

thx again

map.connect ':username', :controller => "users" , :action => "show"

At the bottom of your routes.rb file.

If you do

map.connect ':username', :controller => "users" , :action => "show"

you'll need to look for params[:username] instead of params[:id] when you look up the record.