Question

I've asked at github, but will try asking here as well. Nothing wrong with being "resourceful" ;-). Using friendly_id 4.

I created a user with slug => "123 foobar". This user has an id of 200.

When doing User.find('123-foobar'), it returns the user with id 123, instead of user 200.

Is this a bug?

Was it helpful?

Solution

The find method, (when the first argument is not a symbol) finds by primary key. If you want the slug to be the primary key then do the following:

class User < ActiveRecord::Base
  set_primary_key :slug
end

Doing so, find will find by the slug string, and to_param will return the string from the slug. Your path and url helpers should use the slug too. Your foreign keys will also have to use slug. However, now, find will not find by id.

If you want the id to work as always and/or you don't want all that change in behavior, but the slug is an alternate search method for the user, then search by the following:

User.find_by_slug('123-foobar')

Your routes will be OK, but if the slug is in the URL where the :id goes, it will be passed to the controller in params[:id]. So you can use the same URLs, controllers, and actions with the slug and the id, but your controller will have to figure out which to search by.

class User < ActiveRecord::Base
  def self.slug?(key)
    /^\d*-./ =~ key
  end

  def self.find_from_key(key)
    slug?(key) ? find_by_slug(key) : find(key)
  end
end

class UsersController < ApplicationController
  def edit
    @user = find_from_key(params["id"])
    ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top