LoginSignup
182
181

More than 5 years have passed since last update.

Rails でリンクパスを生成する方法色々・・とRails console で 生成される path を確認したい時

Posted at

Polymorphic URL 使うといいよ!という話

参考ページ:
Rails Best Practices - Generate polymorphic url

Rails初学者が出会うpathの生成ヘルパーから、一歩進んだパス生成方法について、グダグダと書く。

前提

例に使用するScaffold

$ ./bin/rails g scaffold Question title:string content:text
$ ./bin/rails g scaffold Answer content:text question:references

Question has_many Answers.
Answer belongs_to Question.

とする。

app/models/question.rb
class Question < ActiveRecord::Base
  has_many :answers
end
app/models/answer.rb
class Answer < ActiveRecord::Base
  belongs_to :question
end

Routingは標準REST

親子関係があるので、ルーティングをネスト
(この方がネストしたリンクパスを生成する方法も一緒に書けるので)

config/routes.rb
resources :questions do
  resources :answers
end

出来上がったルーティング

$ ./bin/rake routes
              Prefix Verb   URI Pattern                                        Controller#Action
    question_answers GET    /questions/:question_id/answers(.:format)          answers#index
                     POST   /questions/:question_id/answers(.:format)          answers#create
 new_question_answer GET    /questions/:question_id/answers/new(.:format)      answers#new
edit_question_answer GET    /questions/:question_id/answers/:id/edit(.:format) answers#edit
     question_answer GET    /questions/:question_id/answers/:id(.:format)      answers#show
                     PATCH  /questions/:question_id/answers/:id(.:format)      answers#update
                     PUT    /questions/:question_id/answers/:id(.:format)      answers#update
                     DELETE /questions/:question_id/answers/:id(.:format)      answers#destroy
           questions GET    /questions(.:format)                               questions#index
                     POST   /questions(.:format)                               questions#create
        new_question GET    /questions/new(.:format)                           questions#new
       edit_question GET    /questions/:id/edit(.:format)                      questions#edit
            question GET    /questions/:id(.:format)                           questions#show
                     PATCH  /questions/:id(.:format)                           questions#update
                     PUT    /questions/:id(.:format)                           questions#update
                     DELETE /questions/:id(.:format)                           questions#destroy

Railsでリンクパスを生成する方法

XXX_path 方式

初心者的には一番最初に出会う王道的パスの生成方法

上記 rake routes で出てきた Prefix を XXX に入れれば良い。

例: Question#showへのパス

question GET    /questions/:id(.:format)                           questions#show

なので question_path :idがあるのでオブジェクトを引数に渡す

app/views/questions/index.html.haml
= link_to @question.title, question_path(@question)

Rails consoleで合ってるか確認

$ ./bin/rails c
pry> @question = Question.first
pry> app.question_path(@question)
=> "/questions/1"

ネストしてる場合

例: Answer#showへのパス

question_answer GET    /questions/:question_id/answers/:id(.:format)      answers#show
app/views/answers/index.html.haml
%ul
  - @question.answers.each do |answer|
    %li= link_to answer.id, question_answer_path(@question, answer)

Rails consoleで合ってるか確認

$ ./bin/rails c
pry> @question = Question.first
pry> answer = @question.answers.first
pry> app.question_answer_path(@question, answer)
=> "/questions/1/answers/1"

polymorphic_path 方式

モデルから該当のパスをジェネレートさせる方法 polymorphic_path で書きなおしてみる。

app/views/questions/index.html.haml
= link_to @question.title, @question

モデルから類推してちゃんとパスを生成してくれる。

Rails consoleで合ってるか確認

appにいきなりオブジェクトを渡してもダメなので、consoleでは明示的に polymorphic_path と書く。

$ ./bin/rails c
pry> @question = Question.first
pry> app.polymorphic_path(@question)
=> "/questions/1"

ネストしてる場合

polymorphic_path で複数モデルを渡す場合、配列として渡す。

app/views/answers/index.html.haml
%ul
  - @question.answers.each do |answer|
    %li= link_to @answer.id, [ @question, answer ]

Rails consoleで合ってるか確認

$ ./bin/rails c
pry> @question = Question.first
pry> answer = @question.answers.first
pry> app.polymorphic_path([@question, answer])
=> "/questions/1/answers/1"

配列で渡さないと ArgumentError : wrong number of arguments (1 for 0) になってしまう。

モデルが不要なパスを polymorphic_url で生成する方法

newとかindexみたいに、モデルが不要な場合

XXX_path方式

= link_to '新しく質問する', new_question_path

polymorphic_path 方式

シンボルで指定する。

以下の3つの方法は、どれも同じパスを生成できる。

= link_to '新しく質問する', [ :new, :question ]
= link_to '新しく質問する', polymorphic_path([ :new, :question ])
= link_to '新しく質問する', new_polymorphic_path(:question)

ネストしてる場合

= link_to '新しく回答する', [ :new, @question, :answer ]
= link_to '新しく回答する', polymorphic_path([ :new, @question, :answer ])
= link_to '新しく回答する', new_polymorphic_path([ @question, :answer ])
182
181
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
182
181