web-dev-qa-db-ja.com

Rails:id urlパラメータの代わりに:nameを含むルート

「companies」という名前のコントローラーがあり、各企業のURLではなく:idで示されているURLではなく、url/company/Microsoftの代わりにurl/company/3などのURLを使用したいと思います。

私のコントローラーでは、

 def show
   @company = Company.find(params[:name])
 end

Urlには他のパラメーターはないので、Railsは:nameが会社モデルの:name列を参照していることを理解します。ここの魔法はルートにあると思います。しかし、この時点で立ち往生しています。

27
dscher

params

一番下の行は間違った解決策を見ているということです-paramsハッシュキーはかなり無関係であり、それらに含まれるデータをより効果的に使用できる必要があります。

ルートは次のように構築されます。

#config/routes.rb
resources :controller #-> domain.com/controller/:id

これは、このルートをリクエストする場合、domain.com/controller/your_resourceparams[:id]ハッシュ値はyour_resourceになることを意味します(params[:name]またはparams[:id]と呼ばれるかどうかは関係ありません)

-

friendly_id

friendly_idを推奨するいくつかの答えがある理由は、これがfindActiveRecordメソッドをオーバーライドし、 slugを使用できるためです。 クエリ内:

#app/models/model.rb
Class Model < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: [:slugged, :finders]
end

これにより、次のことが可能になります。

#app/controllers/your_controller.rb
def show
    @model = Model.find params[:id] #-> this can be the "name" of your record, or "id"
end
12
Richard Peck

Rails 4.0+の良い答え:

resources :companies, param: :name

オプションで、only:またはexcept:リストを使用してルートを指定できます

uRLを作成する場合は、関連モデルのActiveRecord :: Base#to_paramをオーバーライドできます。

class Video < ApplicationRecord
  def to_param
    identifier
  end

  # or
  alias_method :to_param, :identifier
end

video = Video.find_by(identifier: "Roman-Holiday")
edit_videos_path(video) # => "/videos/Roman-Holiday"
69
Matrix

正直なところ、to_paramの-​​モデル。これにより、company_pathヘルパーは正しく動作します。

注:複雑な名前用に個別のスラッグ列を作成しますが、それは私だけです。これは単純なケースです。

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

次に、読みやすさのためにルートparamを変更します。

# The param option may only be in Rails 4+,
# if so just use params[:id] in the controller
resources :companies, param: :name

最後に私のControllerで正しい方法で調べる必要があります。

class CompaniesController < ApplicationController
  def show
    # Rails 4.0+
    @company = Company.find_by(name: params[:name])
    # Rails < 4.0
    @company = Company.find_by_name(params[:name])
  end
end
11
Azolo

この目的にはfriendly_idを使用することをお勧めします。 friendly_id 4と5には違いがあることに注意してください。friendly_id4では、次のように使用できます。

 @company = Company.find(params[:id])

ただし、friendly_id 5ではこれを行うことができません。以下を使用する必要があります。

 @company = Company.friendly.find(params[:id])

Params [:id]ではなくparams [:name]を使用する場合は、routes.rbのルートをオーバーライドする必要があります。例えば

 get '/companies/:name', to: "companies#show"

これらの情報がお役に立てば幸いです

6
The Lazy Log

実際にこれを実装する魔法はありません。モデルでto_paramを正しく実装することにより(推奨されません) 自分でビルド のいずれかを使用する必要があります。

friendly_idを使用しますが、うまく機能します。

5

Model.find(primary_key)
デフォルトのパラメーターはprimary_key idです。他の列を使用する場合は、Model.find_by_xxxを使用する必要があります。

def show
  @company = Company.find_by_name(params[:name])
end
2
brick