2017-05-04 5 views
0

を私は今、そのURLを作成するためのコードがある

パスヘルパーでデフォルト以外の属性を使用して、代わりに:ID

get 'book/:id' => 'books#show', as: :book 

のようなルートを持っている私は

を持っている:

book_path @book 
コントローラで

@book = Book.find(params[:id]) 

ここまでは順調ですね。さて、このIDは明らかに内部のActiveRecordまたはデータベースの主キーです。

は、私が代わりに

欲しい、私は(この架空の例では)代わりにISBNを使用します。私はそうすることができます:

get 'book/:isbn' => 'books#show', as: :book 
book_path(isbn: @book.isbn) 
@book = Book.find_by(isbn: params[:isbn]) 

これは少し冗長です。私はアプリケーション全体でこのモデルのために "isbn"という大会をしたいと思います。誰もそれを気にする必要はありません。ですから、私の3行は次のようになります:

get 'book/:isbn' => 'books#show', as: :book 
book_path @book # (!) 
@book = Book.find(params[:isbn]) # (!) 

私の願いが叶うように経路を設定することは可能ですか?明らかに、これは自動的にを実行します。少なくとも、ユーザーがURLにISBNを表示するGET要求の場合です。

重要な場合は、#isbn属性は通常の意味での主キーではありませんが、テーブルに特定のISBNを持つレコードが1つしかないことが保証されています。したがって、少なくともプライマリ・キー契約のこの部分は達成されます。

+0

[to_param](https://apidock.com/rails/ActiveRecord/Integration/to_param)メソッドをチェックしましたか? – Sajan

+0

私はしていない!ありがとう、それは素晴らしい作品、2つのより緊急の問題を解決します。後見では、私は '#find'を好むと思うので、とにかく内部IDに固執してください。ミニ回答を作成すると、私の受諾が得られます。 – AnoE

答えて

0

Railsのデフォルト:idパラメータを上書きするには、あなたがto_paramメソッドを使用することができます:あなたはそれのために任意の宝石を使用して任意の問題を持っていない場合

book = Book.find_by(isbn: '123456') 

class Book < ActiveRecord::Base 
    def to_param # overridden 
    isbn 
    end 
end 

とコントローラでは、 、それから私はあなたに一見を与えるべきであることを示唆するfriendly_id宝石。このような場合、これは良い仕事です。あなたのbook.rbで/book/:isbn

book#showから
match '/book/:isbn' => 'book#show', via: :get, as: :show_book 

に合わせて、あなたのroutes.rb、利用の試合で

0

、あなたはISBN代わりのIDに基づいて見つけるために、findメソッドをオーバーライドすることができます。線に沿って何か:

def self.find(*args) 
    c = Book.select("id").find_by(name: args[0]) 
    args[0] = c.id 
    super(args) 
end 

これは、最初のisbnで検索し、idを使用しますが、それは findメソッドを呼び出します。 (私はこれをテストしていないので、それを複数のisbnで動作させるために修正する必要があります)

しかし、これが推奨されているかどうか、そしてそれが何を警告するかわかりません。

代わりに、find_by_isbn[params[:isbn]]を使用しないでください。 find_by(:isbn, params[:isbn])より読みやすくなります。

関連する問題