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 B.,
#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
On Sun, Jan 25, 2009 at 2:21 PM, Louis-Pierre D. <
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 →
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.
Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)
On Sun, Jan 25, 2009 at 5:21 PM, Louis-Pierre D.
Ok… I’ll try that then… Thx a lot for helping…
Louis-Pierre
You don’t need to do self.username, just username will suffice
On 26/01/2009, at 20:42, MatthewRudy [email protected]
On Jan 25, 9:22 pm, Chris J. [email protected] wrote:
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 R.
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).
Ryan B.
Mocra - Premier iPhone and Ruby on Rails Consultants
w - http://mocra.com
e - [email protected]
p - +61 432 937 289 or +61 7 3102 3237
skype - radarlistener
Brian H. 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
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.
map.connect ‘:username’, :controller => “users” , :action => “show”
At the bottom of your routes.rb file.
Ryan B.
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.