Railsのルーティング設定で特定のアクションを除外しつつ、新規のアクションも追加したい時のメモ

rails

現在Railsでスマホ向けAPIを絶賛開発中なのですが、タイトルにかいたような事を実現する為に四苦八苦したので久しぶりにお勉強ノートPOSTです。

ちなみに環境はRails 3.2.17 で、本日の体調は “花粉症くらい気味”

なお、公式(?)のドキュメントとか見たり検索とかしてもコレというものが引っかからなかったのは、一般的にやらない事なのか、やり方が一般的ではないのか、それとも当たり前の事すぎて記事がないのか のどれかであるが、一番最後な可能性を感じる。

今日の目標

たとえば、 “ebi” (エビと読むこととする)なるリソースがあったとして、コントローラがebis_controller.rbだったとする。
※恵比寿コントローラにしか見えないからこの例えはやっぱり失敗だった。

このコントローラでは 特定のアクションを使わない、例えばneweditのアクションを使わないので、それらをルーティングから除外したい。
そのため、

resources :ebis, only => [:index, :show, (略)]

と書いていけば良いことは学んだのだが、これの他にアクションを追加したい(index,show,new,create,edit,destroy)以外のアクションを追加したい。

試行錯誤

まず、アクション追加時のルーティングで、特定のid付きurlで定義したい場合は


resources :ebis do
  member do
   ワッショイ(ΦωΦ)
  end
end

とかいて、このワッショイの中に追加のアクションの定義を書けば良いとされている。
(ざっくりしすぎててスマソ。)
たとえば以下の2つのアクションを追加したかったとする。

例)
post 'grade_up_lobster'
put 'change_shrimp'

最初、無垢な気持ちで以下の用に書いてみた。

resources :ebis, :only => [(略)]
resources :ebis do
  member do
    post 'grade_up_lobster'
    put 'change_shrimp'
  end
end

すると、 rake routes で確認したらば 結局only以外のアクションメソッドも全てルーティング設定されてしまった。

                ebis GET    /ebis(.:format)                          ebis#index
                 ebi GET    /ebis/:id(.:format)                      ebis#show
ebi_grade_up_lobster POST   /ebis/:ebi_id/grade_up_lobster(.:format) ebis#grade_up_lobster
   ebi_change_shrimp PUT    /ebis/:ebi_id/change_shrimp(.:format)    ebis#change_shrimp
                     GET    /ebis(.:format)                          ebis#index
                     POST   /ebis(.:format)                          ebis#create
             new_ebi GET    /ebis/new(.:format)                      ebis#new
            edit_ebi GET    /ebis/:id/edit(.:format)                 ebis#edit
                     GET    /ebis/:id(.:format)                      ebis#show
                     PUT    /ebis/:id(.:format)                      ebis#update
                     DELETE /ebis/:id(.:format)                      ebis#destroy

なお、後半のブロックを回す際に結局対象からはずしたルーティングも設定されてしまったのかな?と思って :only の行をブロックの後に書いてみても結果は同じだった。

別に、コントローラ内にアクションを書いていなければルーティングされていても実行されないんだから良くねー?! っていう囁きもあったが、気持ちが悪いのでなんとか不要なアクションをはずしたい。。 このままでは grade_up_lobsterメソッドで伊勢海老に進化した海老に _method=>DELETE と書かれた不吉なHTTPリクエストが飛んできてしまう。。(実行するものがないけども。)

解決方法

よくよく考えたら、resouces ってメソッドなんだから、ブロック渡す前に引数で追加できるんじゃね? って思って山勘で書いてみたら動いてしまった。

たとえばこんな感じ

  resources :ebis, :only => [:index, :show] do
    member do
      post 'grade_up_lobster'
      put 'change_shrimp'
    end
  end

これを記述して、改めて $rake routesを実行してみたらば

grade_up_lobster_ebi POST   /ebis/:id/grade_up_lobster(.:format) ebis#grade_up_lobster
   change_shrimp_ebi PUT    /ebis/:id/change_shrimp(.:format)    ebis#change_shrimp
                ebis GET    /ebis(.:format)                      ebis#index
                 ebi GET    /ebis/:id(.:format)                  ebis#show

へぇー (*´ω`*) ちゃんとdeleteとかが消えてる。ありがたや。

まとめ

・routes.rbで、ブロック書く前に他の記述もできる
・rubyおもしろい
・今月末までにAPIを稼動させられるか毎晩不安

おわり( ´∀`)

2014-03-11 | Posted in RailsNo Comments » 


関連記事

Comment





Comment



*