RailsのActiveResourceに対応したControllerの最小限のコード

検索でヒットするものは、Rails本化したものの残骸だったり(なぜ消すんだろか、古いから?)、知りたいところが省略されてたりと完全でないものばかりなのでメモ。
基本的にはscript/generate scaffold ...で生成されたものがActiveResource対応しているのですが、そこからブラウザ用HTMLのためのコードを取り除いたもの。

controller

app/controllers/bookmarks_controller.rb

class BookmarksController < ApplicationController
  # GET /bookmarks.xml
  def index
    render params[:format].to_sym => Bookmark.find(:all)
  end
  # GET /bookmarks/new.xml
  def new
    # returns with default value?
    bookmark = Bookmark.new
    render params[:format].to_sym => bookmark
  end
  # GET /bookmarks/0/edit
  def edit
    # editor for human?
    bookmark = Bookmark.find(params[:id])
  end

  # POST /bookmarks.xml
  def create
    bookmark = Bookmark.new(params[:bookmark])
    if bookmark.save
      render params[:format].to_sym => bookmark,
      :status => :created, :location => bookmark
    else
      render params[:format].to_sym => bookmark.errors,
      :status => :unprocessable_entity
    end
  end
  # GET /bookmarks/0.xml
  def show
    bookmark = Bookmark.find(params[:id])
    render params[:format].to_sym => bookmark
  end
  # PUT /bookmarks/0.xml
  def update
    bookmark = Bookmark.find(params[:id])
    bookmark.update_attributes(params[:bookmark])
    # bookmark.url = params[:bookmark][:url]
    # bookmark.title = params[:bookmark][:title]
    if bookmark.save
      head :ok
    else
      render params[:format].to_sym => bookmark.errors,
      :status => :unprocessable_entity
    end
  end
  # DELETE /bookmarks/0.xml
  def destroy
    # Bookmark.delete(params[:id])
    bookmark = Bookmark.find(params[:id])
    bookmark.destroy
    head :ok
  end
end

createメソッドでは、ActiveResource側で、Locationヘッダを作成後のidの素として使用しているため、renderでの:locationの設定が必須です。

以下のrouteでマッピングされていたのでいれたけど、ActiveResource側で使っている気配もないようなので、newやeditメソッドは不要かもしれない。

routes

config/routes.rb

ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
  map.resources :bookmarks
end

コントローラをActiveResource対応にするには、routes設定で、map.resourcesメソッドに対応させるコントローラ名を渡すことで、上記のコントローラメソッドにわたる。

ActiveResource

class Bookmark < ActiveResource::Base
  self.site = "http://localhost:3010/"
  # self.element_name = "bookmark"
  # self.format = :xml # or :json
end

クラス名を変えるときは、element_nameを対象resourceに合わせる

lib/xxx.rbなどにおいておいて./script/consoleを立ち上げ、以下のように使う:

require "xxx"

bs = Bookmark.find(:all)
b = Bookmark.new
b.url = "http://www.yahoo.com"
b.title = "Yahoo!"
b.save

b = Bookmark.find(0)
b.title = "Yahoo.com!"
b.save

b.destroy

Model, 設定等すべての変更

app/models/bookmark.rb

class Bookmark < ActiveRecord::Base
  validates_uniqueness_of :url
  validates_presence_of :url
  validates_presence_of :title
end

db/migrate/xxx_create_bookmarks.rb

class CreateBookmarks < ActiveRecord::Migration
  def self.up
    create_table :bookmarks do |t|
      t.column :url, :text, :unique => true, :null => false
      t.column :title, :text, :null => false, :default => ""
      t.timestamps
    end
  end

  def self.down
    drop_table :bookmarks
  end
end

textにuniqueが利くかどうかは不明

実行

rake db:migrate
./script/server -b 0.0.0.0 -p 3010