Topic: Replace :id with other attribute in routes?

Hi,

is there a way who to use a different attribute then the id in routes and stil remain Resourceful (which should also mean that the helpders function)?
If I head for example a book store, then it would look nice to have an ISBN number insteat of a number that has no meaning.
So I want: MyApp/book/978-3-86680-192-9
And book_path(@book) should also deliver such an URL.

How can I do that?

Thanks!

Re: Replace :id with other attribute in routes?

If you put this in routes.rb

match '/foobar/:strange' => 'foobar#show'

Then all you'd do is this in your foobar_controller.rb

def show
   @foobar = Foobar.find(params[:strange])
end

Still restful,  just not the rails convention

Last edited by BradHodges (2012-02-05 16:15:20)

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: Replace :id with other attribute in routes?

Sure I could do that, but then I could not use the helper methods to create my links, right? - which I want!

And - if possible - I want to stay within the the rails conventions. Is there a way how to do that?

Re: Replace :id with other attribute in routes?

Like this?

def class Foobar << ActiveRecord::Base
  set_primary_key :strange
end

Then

edit_foobar_path(@foobar)

would work, and send @foobar.strange as the route component

Your RESTFul routes would all change, i.e.

match '/foobar/:strange/edit' => 'foobar#edit'

Never tried this, but it should work.

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: Replace :id with other attribute in routes?

Of course,  you database would have to use the :strange attribute as it's primary key.

Not really sure if this is what you're after though???

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: Replace :id with other attribute in routes?

Yes, this is exactly what I am looking for.
Unfortunately a new problem now appears: I created everything with "rails generate scaffold Something name:string" , before running rake db:migrate I added :primary_key to the name column in the migration file. Then I added "set_primary_key :name" to my model. When I now try to create a new entry in that table (with the generated form), this error occurs:

ActiveModel::MassAssignmentSecurity::Error in SomethingsController#create
Can't mass-assign protected attributes: name 

If I remove the "set_primary_key :name" then everything works fine during creation - except that the IDs instead of the name appear in the links.
When I then again add the "set_primary_key :name" to the model, the URLs are as I want them - but, again, I cannot create new entries.

Any ideas how to solve that?

Last edited by echinus (2012-02-06 08:43:15)

Re: Replace :id with other attribute in routes?

try adding

attr_accessor :name

to the model

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: Replace :id with other attribute in routes?

That does not work either.

But meanwhile I found another solution:
Just redefine the to_param and the find method of the model as following:

  def to_param
    #to use the name instead of the ID in URLs
    name
  end
  
  def self.find(s)
    #since URLs use name instead of ID, the find method has to find the record with that attribute
    self.find_by_name(s)
  end

Works fine!

But still, thanks for your support!