基本的な従来のコントローラーのセットアップは次のとおりです。
まず、ルート ショートカットの構文は次のとおりです。
# config/routes.rb
...
resources :products
...
index
すべての製品を にロードし、に 1 つの製品だけをロードするコントローラを次に示しますshow
。
# app/controllers/products_controller.rb
class ProductsController
def index
@products = Product.all
end
def show
@product = Product.find(params[:id])
end
end
ルートファイルのその行は、これらのルートを(とりわけ)提供します:
/products
に行くproducts_controller#index
/products/:id
指定された数値にproducts_controller#show
設定された params[:id] で移動します
最小限の作業できれいな URL を取得する最も簡単な方法は、調べたようにオーバーライドすることto_param
です。
to_param
モデルをURL/リクエストの表現に変換するためにRailsが使用するものです。
デフォルトでは、これは次のとおりです。
class Product
def to_param
self.id
end
end
そのため、Rails がその結果に対して Product.find() を実行するとto_param
、find()
それが の整数に変換されto_i
ます。
params[:id]
がの場合"24"
、Product.find(params[:id])
"24" を整数 24 に変換します。
ただしto_i
、他の例でどのように機能するかを検討してください。
"100".to_i #=> 100
"100-flux-capacitor-2000".to_i #=> 100
つまり、 Product のパラメータ表現が である場合、products#show URL が のように見えても、 は機能し"#{id}-the-product-name"
ます。Product.find(params[:id])
/products/56-ford-taurus
もう一つ:
"I love the Ford Taurus".parameterize #=> "i-love-the-ford-taurus"
ソリューション A
問題の最も簡単な解決策は、次のように to_param をオーバーライドすることです。
class Product
def to_param
"#{id}-#{name.parameterize}"
end
end
この方法の利点は、Product モデルの 1 つのメソッドを変更するだけで、コードの残りの部分が正常に動作することです。
欠点は、URL が次のようになることです。
/products/56-ford-taurus
それ以外の:
/products/ford-taurus
ソリューション B
後者の例が必要な場合はslug
、Products テーブルに列を維持できます。
例:
Product
id: 58
name: Ford Taurus
slug: ford-taurus
次に、次のように to_param をオーバーライドできます。
class Product
def to_param
slug
end
end
これで、params[:id] は「ford-taurus」のようになります。
Product.find("ford-taurus")
find() は整数を必要とするため、もう機能しないため、 に置き換えることができProduct.find(params[:id])
ますProduct.find_by_slug(params[:id])
。
すべての製品に固有のスラグがあることを確認する必要があります.
また、次のような方法でスラッグ作成プロセスを自動化できます。
class Product
before_create :make_slug
private
def make_slug
self.slug = name.parameterize
end
end
そうすれば、作成時に製品の名前を設定して保存するだけで、そのスラッグは「製品名が何であれ」URL に適したものになります。
- プラス面: URL には製品名のみが含まれ、見苦しい製品 ID はありません。
- 欠点: 製品のスラッグを変更すると URL が壊れます。そのため、私の before_filter の例では、製品を保存するときではなく、作成時にのみスラッグを設定します。
Rails が必要な種類の URL を生成するようになったので、次のようなビューでこれらの製品へのリンクを生成できます。
# This would be in views/index.html.erb
<% @products.each do |product| %>
<%= link_to product.name, product %>
<% end %>
各製品に対してこの種の html を生成します。
<a href="/products/56-ford-taurus">Ford Taurus</a> (if you used Solution A)
<a href="/products/ford-taurus">Ford Taurus</a> (if you used Solution B)