member
collectionの各メンバーに対してリソースを追加することができる。
例えば以下があったとする。
resources :author
これに対して、お気に入り機能をつけたい。
以下のようなパスになるはず。
/author/1/favorite
これは以下のように routes.rb
に再現できる。
resources :author do
post :favorite
end
こうすると、railsは以下のパスを認識する。
author/{author_id}/favorite
該当する author.id
を params[:author_id]
で取得できる
ちょっと一工夫
resources :author do
post :favorite, on: :member
end
とすると、railsは以下のパスを認識する。
author/{id}/favorite
該当する author.id
を params[: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