scaffold_resourceでRESTfullなRailsアプリ(2)
scaffold_resourceを試してみる第2段、下のサイトを参考にしてhas_manyな場合を試してみる。
Web 2.0 Technologies: Nested CRUD resources in Rails 1.2
まずscaffoldを作る。post->commentsなhas_manyの関係のモデルの場合
ruby script/generate scaffold_resource Post title:string body:text ruby script/generate scaffold_resource Comment body:text
/db/migrate/002_create_comments.rb へ外部キーを追加、あとhas_many/belongs_toをモデルへ追加
t.column :post_id, :integer class Post < ActiveRecord::Base has_many :comments end class Comment < ActiveRecord::Base belongs_to :post end
/config/routes.rbにmap.resourcesが入っているので修正してhas_manyの構造に
ActionController::Routing::Routes.draw do |map| map.resources :posts do |posts| posts.resources :comments end map.connect ':controller/service.wsdl', :action => 'wsdl' map.connect ':controller/:action/:id.:format' map.connect ':controller/:action/:id' end
あとは細かい部分を修正。
- 使いやすくするために、before_filterで親のpostを@postとして持っておく
- commentsのindex表示を@post.comments.find(:all)に変更
- comment新規作成時にpost_idを保存
- comment関連Viewのリンクを<%= link_to 'Show', comment_path(@post, @comment) %>みたいに変更
class CommentsController < ApplicationControlle before_filter (:get_post) def index @comments = @post.comments.find(:all) respond_to do |format| format.html # index.rhtml format.xml { render :xml => @comments.to_xml } end end def create @comment = Comment.new(params[:comment]) @comment.post_id = @post.id ........... end ............ private def get_post @post = Post.find(params[:post_id]) end end
で、アクセスしてみる
GET /posts/1 #id=1のpostを表示 GET /posts/1/comments #id=1のpostに紐づくcomment一覧 POST /posts/1/comments #id=1のpostに紐づくcomment新規作成 PUT /posts/1/comments/1 #id=1のpostに紐づくcommentの更新 DELETE /posts/1/comments/1 #id=1のpostに紐づくcommentの削除
疑問:postのID=1が params[:post_id]に入ってくるのはなんで?map.resources{|post| post.resources}のおかげ?