How do I move example.com/profiles/1 to example.com/username with friendly_id with username from user model?
-
08-02-2021 - |
質問
I have red docs on friendly_id for rails. It's easy: you set a certain attribute to be the slug.
example.com/username
User has_one profile
Profile belongs_to User
So you see my dilemma. I have no column username in the profile model. How can I link the user model, username field so that I can do example.com/username with friendly_id?
Surely this is relatively simple.
解決
You can use a "catch-all" route at the end of your routes file:
map.connect ':username', :controller => 'profiles', :action => 'show' (this is for Rails 2.3)
And in the profiles controller, method show you check if there is a user with that username, and if it belongs to the current profile
def show
if User.find_by_username(params[:username])
if @current_user == User.find_by_username(params[:username])
# @profile = @current_user.profile
# render projects#show view
else
# flash error message, because the current user tries to access other users profile (in case your app doesn't allow it)
else
# render page not found error
end
end
I had a similar situation for a projects model, from projects/id => /project_name. It is a bit easier in your case because in the db you have unique usernames. Ah, and no extra gems are involved.
他のヒント
In your ProfilesController#show
:
def show
@user = User.joins(:profile).where("profiles.username = ?", params[:username])
end
Routes:
match ':username' => "profiles#show'
Optionally, you can add a method to your User model to make your controller cleaner:
class User < ActiveRecord::Base
def fetch_by_username(username)
joins(:profile).where("profiles.username = ?", username)
end
end
And in your controller:
@user = User.fetch_by_username(params[:username])
You can use a custom method to generate the slug you need.
class Profile < ActiveRecord::Base
has_many :users
has_friendly_id :custom_url_method, :use => :slugged
def custom_url_method
self.user.username.to_url
end
The to_url is from Stringex gem. You can alternatively use one of Babosa's helper methods provided by Friendly_id itself.