route / map.resources の使い方
Rails 2.0 から標準になった、map.resources は RESTfulなコントローラに対応したrouting情報を作ってくれます。
ActiveResource が使えるようになり、外部とのRESTfulな操作が簡単にできてしまいます。
まだサンプル見た程度なので、機能は全部把握できていませんが。
参考 URL
http://d.hatena.ne.jp/zariganitosh/20080203/1202091772 http://rails-recipebook.g.hatena.ne.jp/rrbk/20071019 http://railspress.matake.jp/rails20%E3%81%AErouting%EF%BC%88configroutesrb%EF%BC%89%E3%81%AE%E8%A8%98%E8%BF%B0%E6%96%B9%E5%BC%8F%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81%E3%80%82 http://www.eisbahn.jp/yoichiro/2007/12/3mapresources.html
基本形
map.resources :books
redirect_to :controller => "books", :action => "index" などのようなパスを作成するには次のようにします。
※ @book はモデル
# index books_path books_url # show book_path(@book) # もしくは id を指定 redirect_to @book # new new_book_path # edit edit_book_path(@book) redirect_to [:edit, @book] #redirect_to に渡す場合 # destroy redirect_to book_path(@book), :method => :delete # redirect_to に渡す場合
destroy だけちょっと面倒です。
多段な場合
map.resources :categories, :has_many => :books map.resources :categories, :has_many => [:books, :authors] # 複数指定する場合は配列にする
※ :has_one もある。(map.resource になる)
- 基本のパス生成は同じなので省略
- books:
※@category, @book は各モデル
# index category_books_path # show category_book_path(@category, @book) link_to [@category, @books] # link_to な場合 # new new_category_book_path # edit edit_category_books_path(@category, @book) # …なぜかうまくいかないことがあった link_to [:edit, @category, @book] # destory link_to category_book_path(@book), :method => :delete
やっぱり削除は面倒です。
コントローラを変える
- 1モデル
map.resources :books, :controller => "published_books"
- 多段の場合, has_many とかが使えないので次のようにする
map.resources :categories do |category| category.resources :books, :controller => "published_books" end
生成されるパスを /categories/:id/books/ ではなくて、 /categories/:category_name/books のようにしたいとき
has_many, has_one は使えないので、次のようにします。
もちろん、 :category_name はユニークな値でないとおかしなことになります。
map.resources :categories map.with_options :path_prefix => "/categories/:category_name", :name_prefix => "category_" do |categories| categories.resources :books end
with_options ... do な形にしておけば、追加するときにDRYになります。
パスを生成するときの指定方法を次のようにする。
# index category_books_path(:category_name => @category.name) # show category_book_path(:category_name => @category.name, :id => @book.id) # edit edit_category_book_path(:category_name => @category.name, :id => @book.id) # destroy (redirect_to の場合) redirect_to category_book_path(:category_name => @category.name, :id => @book.id), :method => :delete
コントローラもこちらの形式に対応させて書き直せば、若干面倒くさくなりますがとりあえず動作します。
map.namespace で プレフィックスをつける
パスの前に /admin を追加したい場合、map.namespaceを使えば簡単にできます。
map.namespace :admin do |admin| admin.resources :books end
こうすると、コントローラは Admin::BooksController になり、パス生成も admin_books_path のようになります。