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