2011-01-19 14 views
2

私はカテゴリモデルを持っていて、デフォルトの足場を使ってルーティングしていますresources :categories/category/:idから/category/:nameにパスを変更する方法があるかどうかは疑問です。 routes.rbPretty Paths in Rails

match "/categories/:name" => "categories#show" 

資源線より上とやるために、コントローラでshowアクションを変更:私は追加

@category = Category.find_by_name(params[:name]) 

それは動作しますが、そのようなlink_to some_categoryとしての「魔法のパスは」まだ:idを使用しますフォーマット。

これを行う方法はありますか?これが悪い考えなら(レールが内部的に働く可能性があるため)、これを達成する別の方法がありますか?だから/categories/music、例えば、/categories/3の両方が使えますか?

答えて

5

Railsには、to_paramと呼ばれる素敵なモデルインスタンスメソッドがあり、それはパスが使用するものです。それidデフォルト、しかし、あなたはそれをオーバーライドして、のようなものを生成することができます。詳細情報については

class Category < ActiveRecord::Base 
    def to_param 
    name 
    end 
end 

cat = Category.find_by_name('music') 
category_path(cat) # => "/categories/music" 

を、Rails documentation for to_paramをご確認ください。

EDIT:

それはあなたが複数のオプションを持っている、URLのための理想的ではありませんカテゴリ名になります。 1つは、あなたが言うように、レコードを見つけるときに、gsubにハイフンを含む空白とその逆になります。ただし、より安全なオプションは、name_param(またはそれに類する)というカテゴリテーブルに別の列を作成することです。その後、あなたは、すべてのパスとURL関連のビジネスの名前の代わりに、それを使うことができます。 URL安全な文字列を作成するには、parameterizeインフレクタを使用します。ここで私はそれを行うだろう方法は次のとおりです。

class Category < ActiveRecord::Base 
    after_save :create_name_param 

    def to_param 
    name_param 
    end 

    private 
    def create_name_param 
     self.name_param = name.parameterize 
    end 
end 

# Hypothetical 
cat = Category.create(:name => 'My. Kewl. Category!!!') 
category_path(cat) # => "/categories/my-kewl-category" 

# Controller 
@category = Category.find_by_name_param(param[:id]) # <Category id: 123, name: 'My. Kewl. Category!!!'> 
+0

ありがとうございました!私はこれについて忘れてしまった! –

+0

万が一、カテゴリ内のスペースを扱う良い方法が分かっていますか?たとえば、カテゴリ「2つの単語」は、それをURLの「2つの単語」にしますか?それは私にto_param name.gsub( ""、 " - ")を実行させ、その後find_by_nameを実行するたびに同じことをしますか? params [:name] .gsub( " - "、 "")?しかし、どのように私はマッチパターンを書き直すだろうか? –

+0

私は、私が思っていたよりもうまくいくはずのレールに[parameterize](http://rails.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html#M001063)メソッドがあることがわかりました約。 –

2

あなたはモデルIDに頼るという既存のコードをに壊したくない場合は、このようなあなたのto_paramを定義することができます。

def to_param 
    "#{id}-#{name}" 
end 

ので、あなたのURLの意志http://path/1-some-modelとあなたはまだModel.find(のparams [:ID])を使用してモデルをロードすることができますすることがあるため:

"123-こんにちは世界" .to_i => 123

+0

ありがとう、私はそれを念頭に置いておきます。 –

1

(あなたはユニコードサポートなどを必要とする場合、例えば)あなたが必要とするよりも、おそらくよりは、あなたもfriendly_id等のような「人間が読める形式のURLの支援に見たいと思うかもしれないがされています記載されているhere at Ruby Toolbox