Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding Rails to_param?

How do I get the to_param method to deliver keyword slugs all the time? I have trouble getting it to work with this route:

map.pike '/auction/:auction_id/item/:id', :controller => 'items', :action => 'show'

Earlier the overridden to_param was working for

'items/1-cashmere-scarf'

but fails with 'auction/123/item/1'

Update:

I'm not sure if the syntax is correct[(edit: it's correct: it works :-)], or even efficient.... but using haml, I found that the following code works to generate the desired link ('auction/:auction_id/item/:id')

- for auction in @auctions.sort{|a, b| a.scheduled_start <=> b.scheduled_start}
  -for item in @items
    - unless auction.current_auction
      ... pike_path(auction.auction_id, item)
like image 475
Jesse Avatar asked Dec 21 '08 10:12

Jesse


1 Answers

I'm not sure whether I understand your question. (it's 3:41 AM here)

From what I see, you directly access auction_id method, instead of using pike_path(auction, item) that'd use #to_param.

Also, it might fail for auction/123/item/1 because you haven't changed your controller.

I think it'd be helpful to describe how to get working slugs.

Broadly speaking, if you override #to_param, IDs no longer works. It means, that if you go with slugs, every time polymorpic URL is generated (eg, link_to object, object), it passes to_param's value. It is worth noting that you must change your controller as well.

Personally I think that the best way to generate slugs easily is to use techno-weenie's permalink_fu, adding has_permalink to your model, and then, override to_param. For example

class Auction < ActiveRecord::Base
  has_permalink :title, :slug
end

assuming that you have slug, a string field, and want to slugize your title.

You also need to adjust your controller:

class AuctionsController < ApplicationController
  def show
    @auction = Auction.find_by_slug(params[:id]) || raise(ActiveRecord::RecordNotFound)

    respond_to do |format|
      format.html # show.html.erb
    end
end

Then, you can generate routes, in the views, this way:

link_to @action, @action

By the way, you should NOT sort your actions in the view. The best way is to use named_scope.

like image 167
maurycy Avatar answered Oct 22 '22 07:10

maurycy