ヘンシュウチョ さんの、
「RailsだとWeb APIとか自動生成できるってホント?俺に教えてよ!つーか勉強会やろうぜ」
という発言を切欠に小勉強会をやってきました。
ヘンシュウチョさんはオープンソースXML DB eXistの話。XPathやXQueryなどXML関連は仕様の分裂や議論が絶えないので深追いや混乱が楽しいですね。eXistの日本語ドキュメントは殆どなさそうなので是非公開してほしいです。
yoshukiさんはvimやscreen関係の開発環境の話でした。俺なんかはすぐ開発環境をおそろかにして生産性を下げてしまうので非常に参考になりました。
俺は「土日でサービス作れるようになる」を目指しているので、RESTfulアプリケーションの簡単作成方法を話ました。
スライドだけだとさっぱりなので手順とソースも上げとこうと思います。
ソース:
rest-todo.tar.bz2
手順:
プロジェクトを作成。(面倒なのでsqliteを使います)
$ rails rest-todo -d sqlite3 $ cd rest-todo
scaffold_resourceジェネレーターを使って、Controller, Migrationファイル, route.rbファイルへの設定追加をします。
$ ruby script/generate scaffold_resource Task name:string completed:boolean created_at:timestamp updated_at:timestamp $ tree app app |-- controllers | |-- application.rb | `-- tasks_controller.rb |-- helpers | |-- application_helper.rb | `-- tasks_helper.rb |-- models | `-- task.rb `-- views |-- layouts | `-- tasks.rhtml `-- tasks |-- edit.rhtml |-- index.rhtml |-- new.rhtml `-- show.rhtml
migrateしてからサーバーを起動します。
$ rake db:migrate $ ruby script/server
生成された一覧画面。
Web APIでのCRUDをirbから確認。
$ irb -r 'net/http' > http = Net::HTTP.start('dev', 3000)
>
puts http.get('/tasks.xml').body
>
puts http.get('/tasks/1.xml').body
>
http.post('/tasks.xml', 'task[name]=task3')
>
puts http.get('/tasks.xml').body
>
http.put('/tasks/3.xml', 'task[name]=task3...!!??')
>
puts http.get('/tasks/3.xml').body
>
http.delete '/tasks/3.xml'
>
puts http.get('/tasks.xml').body
認証機能を追加。authenticatedジェネレーターでuserモデルを使ってaccountコントローラーを生成します。
$ ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/acts_as_authenticated $ ruby script/generate authenticated user account $ rake db:migrate
出来たDBを確認。
$ sqlite3 db/development.sqlite3 SQLite version 3.3.8 Enter ".help" for instructions sqlite
>
.tables schema_info tasks users sqlite
>
.schema tasks CREATE TABLE tasks ("id" INTEGER PRIMARY KEY NOT NULL, "name" varchar(255) DEFAULT NULL, "completed" boolean DEFAULT NULL, "created_at" datetime DEFAULT NULL, "updated_at" datetime DEFAULT NULL); sqlite> .schema users CREATE TABLE users ("id" INTEGER PRIMARY KEY NOT NULL, "login" varchar(255) DEFAULT NULL, "email" varchar(255) DEFAULT NULL, "crypted_password" varchar(40) DEFAULT NULL, "salt" varchar(40) DEFAULT NULL, "created_at" datetime DEFAULT NULL, "updated_at" datetime DEFAULT NULL, "remember_token" varchar(255) DEFAULT NULL, "remember_token_expires_at" datetime DEFAULT NULL);
login_requiredメソッドがおかしくて(Basic認証の方だけ)100%認証が通らないのでオーバーライドします。
$ vim app/controllers/application.rb include AuthenticatedSystem def login_required username, passwd = get_auth_data if self.current_user == :false && username && passwd self.current_user = User.authenticate(username, passwd) || :false end logged_in? && authorized? ? true : access_denied end
タスクのCRUD全部に認証をかけます。
$ vim app/controllers/tasks_controller.rb class TasksController < ApplicationController before_filter :login_required (略) end
Jester.jsを使ってJavaScriptからWeb APIと認証の動作を確認します。
$ wget 'http://svn.thoughtbot.com/jester/tags/rel-1.3/jester.js' -O public/javascripts/jester.js $ vim app/views/layouts/tasks.rhtml <%= javascript_include_tag :defaults %>
<
%= javascript_include_tag 'jester' %
>
$ mv app/views/layouts/tasks.rhtml app/views/layouts/application.rhtml
FireBugsから確認します。認証が必要なリソースにアクセスしようとするとBasic認証のWindowが表示されます。
Jester.jsでCRUDの確認。(実際には_methodパラメータによるメソッドエミュレーションを使っているのでPUTやDELETEがPOSTになっています。)
通常のページとWeb APIを同じロジックで認証できるのはシンプルですっきりした感じがします。派生する話題も色々ありそうで今後も手っ取り早い作り方をチェックしていきたいと思います。