How do I move example.com/profiles/1 to example.com/username with friendly_id with username from user model?

StackOverflow https://stackoverflow.com/questions/7725147

Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top