0

Using Rails 2.3.8, and friendly_id.

Person model:

class Person < ActiveRecord::Base
  # Nice URL's in Rails.
  def to_param
    "#{login.downcase.gsub(/[^[:alnum:]]/,'-')}".gsub(/-{2,}/,'-')
  end
end

People controller:

class PeopleController < ApplicationController
  def show
    @person = User.find(params[:id]) 

    if current_user == @person
      @shops = @person.shops.paginate(:page => params[:page], :order => order)
    else
      @shops = @person.shops.by_status('published').paginate(:page => params[:page], :order => order)
    end

  end

end

User model (stripped):

class User < ActiveRecord::Base
  extend ActiveSupport::Memoizable
  acts_as_authentic do |c|
    c.validate_email_field = false
    c.validate_login_field = false
  end

  attr_accessible :login, :email, :password, :password_confirmation, :name, :location, :website,
                  :allow_follower, :allow_message, :allow_updates, :allow_newsletter, :avatar, :role, :remember_me

  # Returns name or login if name is blank
  def full_name
    if self.name.blank?
      login.strip
    else
      (self.name || '').strip
    end
  end
  memoize :full_name

  # Nice URL's in Rails.
  def to_param
    "#{login.downcase.gsub(/[^[:alnum:]]/,'-')}".gsub(/-{2,}/,'-')
  end

end

The to_param definition in People.rb and User.rb don't work.

All pages under Users controller are purely for user's account settings and is for private view, so I don't need any nice URL in it. But I have created a People controller to showcase as the user's profile for public view.

The people URL currently is http://abc.com/people/1, I want to turn it to http://abc.com/people/login-name-here, yet without breaking the @person = User.find(params[:id]) in people's controller because I need to perform a sphinx search in it.

What can I do to achieve it? Thank you.

Victor
  • 13,010
  • 18
  • 83
  • 146

1 Answers1

0

Hoping this will help someone else coming here, if you have already solved this.

It shouldn't break the User.find(params[:id]) if using friendly_id .. In fact, both person/login-name and person/123 routes with both work.

Because you're using rails 2.3.8, You will need to use friendly_id version 3.2.1.1 is the latest version that supports activerecord 2.3.x - (found here https://rubygems.org/gems/friendly_id/versions/3.2.1.1). Version 4.x needs activerecord 3+ so won't be compatible.

  • Firstly, install the gem (if not already done), run the generator etc ... (more help can be provided on this if needed)

on your user table I recommend adding a cached_slug columns (as a string)

Then, following that ...

Just add the following to app/models/user.rb

has_friendly_id :login, :use_slug => true, :cache_column => 'cached_slug'

and you should be able to get rid of the to_param methods on your models. Remember to update attr_accessible to avoid issues.

Also, you can create an instance method that returns a string for use with friendly_id, eg:

has_friendly_id :stripped_login, :use_slug => true, :cache_column => 'cached_slug'

Then just add:

def stripped_login
  login.gsub(/regexhere/)
end

FriendlyId downcases the slug for you.

NOTE: I recall there being a problem with including the has_friendly_id before the attr_accessible items. I'm almost certain it needs to be placed after that line, but I can't seem to recall at the moment.

Matenia Rossides
  • 1,406
  • 9
  • 35