0

数か月前に書いたアプリケーションに戻り、いくつかの小さな調整を加えようとしています。現在、すべてのエントリのループをProduct使用してすべての製品がリストされているモデルとカタログ ページがあります。 eachProduct

サイトを安全に保つためにhttp://.../products/...、認証ログインを設定しました。そのため、パスワードを持つユーザーのみが/products/index製品の詳細を表示し、編集し、製品を 1 つずつ表示できます (ページを表示)。

すべての製品がリストされているページから、1 つの製品の詳細のみを含むページ (つまり、個々の製品のページ) にリンクしたいと考えています。

Productの検索機能を使用してモデルから製品を検索できることは承知していProduct IDますが、この製品のリスト用に適切な URL を自動的に作成するにはどうすればよいですか?

要約すると、ページに 10 個の製品のリストがある場合、ユーザーが製品をクリックして というページにルーティングできるようにする最善の方法は何http://..../shop/specific_products_nameですか? 私は少し読んだことがto_paramありますが、いくつかの利点があるように見えますが、これらのページを作成する賢明な方法を見つけるのに苦労しています

御時間ありがとうございます

4

1 に答える 1

1

基本的な従来のコントローラーのセットアップは次のとおりです。

まず、ルート ショートカットの構文は次のとおりです。

# 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_paramfind()それが の整数に変換され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)
于 2012-10-08T20:45:34.090 に答える