Rails routing(member/collection)

member

collectionの各メンバーに対してリソースを追加することができる。
例えば以下があったとする。

resources :author

これに対して、お気に入り機能をつけたい。
以下のようなパスになるはず。
/author/1/favorite

これは以下のように routes.rbに再現できる。

resources :author do
  post :favorite
end

こうすると、railsは以下のパスを認識する。
author/{author_id}/favorite
該当する author.idparams[:author_id]で取得できる

ちょっと一工夫

resources :author do
  post :favorite, on: :member
end

とすると、railsは以下のパスを認識する。
author/{id}/favorite
該当する author.idparams[:id]で取得できる

collection

collectionの全体に対してroutingを設定したい時につかう。
つまり、collectionの各要素を認識するような idが必要ないということ。

間違い

resources :author do
  get :search
end

こうすると以下のようなroutingができてしまう。

            author_search GET    /author/:author_id/search(.:format)                                                      author#search

authorの各instanceに対して何かを検索してる感

正解

resources :author do
  get :search, on: :collection
end

とすると、以下のようになる。

      search_author_index GET    /author/search(.:format)                                                                 author#search

memberのちょっと使えた話

共通処理のメソッドを作成することができるようになりました!

Before

これを知る前は、以下のようにしてました。

resources :author do
  post :favorite
end
...

def show
  @author = Author.find_by(id: params[:id])
end

def favorite
  @author = Author.find_by(id: params[:author_id])
  current_user.likes.create(author: @author)
end

After

以下のように変更できて見通しが良くなりました。

resources :author do
  post :favorite, on: :member
end
...
before_action :set_author

def show
end

def favorite
  current_user.likes.create(author: @author)
end

private
def set_author
  @author = Author.find_by(id: params[:id])
end

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です