RoR で実現する Ajax アプリ (写経) その 1

明日から ip unreachable ってコトで急いでナニしてみる。

事前準備

railsscript.aculo.us の最新版を svn にて co との事。_すくりぷたきゅらす_って rails と結構近しい関係にあるなんて知らなんだ。とゆー事で以下。

$ svn co http://dev.rubyonrails.org/svn/rails/trunk rails
$ svn co http://dev.rubyonrails.org/svn/rails/spinoffs/scriptaculous scriptaculous

で、rails なナニを作成。最新版を使うんで作り方が少々違う、と。

$ ruby railties/bin/rails todo
(多いので略)
$

あと、先に co した rails とか script.aculo.us などもコピィ、との事。

$ cp rails todo/vendor/ -r
$ cp scriptaculous/lib/*.js todo/public/javascripts/.
$ cp scriptaculous/src/*.js todo/public/javascripts/.

Active Record の validate メセジ日本語化な準備

以下。

$ wget http://rails2u.com/tmp/active_record_ja.rb.txt
--12:19:50--  http://rails2u.com/tmp/active_record_ja.rb.txt
           => `active_record_ja.rb.txt'
rails2u.com をDNSに問いあわせています... 60.46.130.54
rails2u.com|60.46.130.54|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 2,810 (2.7K) [text/plain]

100%[====================================>] 2,810         --.--K/s             

12:19:51 (36.73 KB/s) - `active_record_ja.rb.txt' を保存しました [2810/2810]

$ ls
active_record_ja.rb.txt  bookmark.before.login_engine  scriptaculous
bookmark                 bookmark.old                  todo
bookmark.20060801        rails
$ cp active_record_ja.rb.txt todo/lib/active_record_ja.rb
$

conifg/environment.rb に以下の命令を追加する必要あり、との事。

require 'lib/active_record_ja.rb'

migrate

migration なナニが、とゆー意味ではこの記事はポイント高いな。あまり本買ってないんでアレですが、UT 方面をきちんと記述したものは少ないのかな? そーゆー意味では AWDwR は凄いな、と。(ただし、わしが持っているのは migration な記述は一切ナシ)

DB 作って

面倒クセェのでがーんと作っちゃえ。とりあえずサーバ側で。

$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14 to server version: 5.0.20-Debian_1-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create database todo default character set utf8 ;
Query OK, 1 row affected (0.75 sec)

mysql> grant all privileges on todo.* to xxx@192.168.0.1
    -> identified by 'xxx' ;
Query OK, 0 rows affected (1.35 sec)

mysql> \q
Bye
$

テキトーっすね、はい。次は config/database.yml ッス。しかも development のみ。

config/database.yml

development:
  adapter: mysql
  database: todo
  username: xxx
  password: xxx 
  host: 192.168.0.1
migration

どんどんヤリます。

$ script/generate migration InitialSchema
      create  db/migrate
      create  db/migrate/001_initial_schema.rb
$

migration のススメ方も再チェックした方が良いな。(独り言)

で、デキたのを修正。最初はコレ。
db/migrate/001_initial_schema.rb

class InitialSchema < ActiveRecord::Migration
  def self.up
  end

  def self.down
  end
end

diff よりゃデキあがりの方がいいっしょ、テことで以下。(とはいえ、写経ですが)
db/migrate/001_initial_schema.rb

class InitialSchema < ActiveRecord::Migration
  def self.up
    create_table :lists do |t|
      t.column :title, :string
      t.column :created_on, :time
      t.column :updated_on, :time
    end

    create_table :items do |t|
      t.column :list_id, :integer
      t.column :completion, :boolean, :default => false
      t.column :position, :int
      t.column :created_on, :time
      t.column :updated_on, :time
    end
  end

  def self.down
    drop_table :lists
    drop_table :itmes
  end
end

上書き保存して、アレ。

$ rake migrate
== InitialSchema: migrating ===================================================
-- create_table(:lists)
   -> 1.0010s
-- create_table(:items)
   -> 0.2824s
== InitialSchema: migrated (1.2840s) ==========================================

$

model 作成

事前準備は完了との事にて、まずは model の作成との事。写経なんでどんどんヤリます。

$ script/generate model list
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/list.rb
      create  test/unit/list_test.rb
      create  test/fixtures/lists.yml
      exists  db/migrate
      create  db/migrate/002_create_lists.rb
$ script/generate model item
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/item.rb
      create  test/unit/item_test.rb
      create  test/fixtures/items.yml
      exists  db/migrate
      create  db/migrate/003_create_items.rb
$

なんか db/migrate/ にいくつかデキてるあたり、微妙ですが構わず進めます(まだ残りが 6 頁あるんですがどうしよう ...)。とりあえず、写経を。

app/models/list.rb

class List < ActiveRecord::Base
  has_many :items, :order => 'position', :dependent => true
  set_field_names :title => 'タイトル'

  validates_presence_of :title
end

app/models/item.rb

class Item < ActiveRecord::Base
  belongs_to :list
  set_field_names :note => 'やること'
  acts_as_list :scope => :list

  validates_presence_of :note
end

acts_as_* とか set_field_names とかって何だー、と言いつつ進めちゃう。

リスト作成

大枠のテンプレ作成との事にて、app/views/layouts/default.rhtml がそうである事を初めて知った (こら)。ソースは以下との事。って一から作成なのか。

app/views/layouts/default.rhtml

<html>
<head>
<meta http-equiv="Content-Type"
	content="text/html; charset=UTF-8" />
<title>Tascas</title>
<%= stylesheet_link_tag "style" %>
<%= javascript_include_tag "prototype" %>
<%= javascript_include_tag "scriptaculous" %>
</head>

<body>
<div class='main'>
<h1>Tascas</h1>
<%= @content_for_layout %>
</div>
</body>
</html>
コントローラ作成

試験がデキんのでがんがん入力。コントローラ作成、らしい。

$ script/generate controller task
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/task
      exists  test/functional/
      create  app/controllers/task_controller.rb
      create  test/functional/task_controller_test.rb
      create  app/helpers/task_helper.rb
$ script/generate controller ajax
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/ajax
      exists  test/functional/
      create  app/controllers/ajax_controller.rb
      create  test/functional/ajax_controller_test.rb
      create  app/helpers/ajax_helper.rb
$
コントローラ実装

で、controller を修正、らしい。最低限との事。テキストはディレクトリ名とか細かい部分で微妙なトコが多いな。(余計

app/controllers/task_controller.rb

class TaskController < ApplicationController
  before_filter :charset
  layout 'default'

  def index
    @lists = List.find_all
  end

  protected
  def charset
    @headers['Content-Type'] = 'text/html; charset=utf-8'
  end
end
index ビューの実装

って、何もナシで index.rhtml の (以下略
そのまま入力。

app/views/task/index.rhtml

<%= form_remote_tag :url => {:controller => 'ajax', :action => 'add_list'},
	:failure => 'alert(request.responseText)',
	:update => { :success => 'tasklists' },
	:position => :bottom,
	:html => { :class => 'add_list' }
%>
<%= text_field_tag 'title' %>
<%= submit_tag '追加する' %>
<%= end_form_tag %>
<div id='tasklists'>
<%= render :partial => 'list', :collection => @lists %>
</div>
add_list の実装

上記 view で指定されている、ajax controller の add_list というアクションを実装、との事。以下で。

app/controllers/ajax_controller/rb

class AjaxController < ApplicationController
  before_filter :charset_plain

  def add_list
    list = List.new(:title => params[:title])
    render_add(list, 'list')
  end

  protected

  def render_add(ar,name, partial_template_name = name)
    if ar.save
      render(:partial => "task/#{partial_template_name}",
             :status => 200, :locales => {name.to_sym => ar})
    else
      render(:text => ar.errors.full_messages.join("\n"),
             :status => 406)
    end
  end

  def charset_plain
    @headers["Content-Type"] = "text/plain; charset=utf-8"
  end

end

部分レイアウトとの事にて app/views/task/_list.rhtml も作成。

app/views/task/_list.rhtml

<div class='tasklist'>
<h2 id='tasklist_<%= list.id %>'>
<%= h list.title %></h2>
</div>

とりあえず、WEBrick 動かしてみたんですが、何をスレば良いのか分からんぞ (爆

動作確認

結論から言うとオチてます。app/config/environment.rb に以下の命令を追加すんのを忘れてました。

config/environment.rb

$ tail config/environment.rb
# (all these examples are active by default):
# Inflector.inflections do |inflect|
#   inflect.plural /^(ox)$/i, '\1en'
#   inflect.singular /^(ox)en/i, '\1'
#   inflect.irregular 'person', 'people'
#   inflect.uncountable %w( fish sheep )
# end

# Include your application configuration below
require 'lib/active_record_ja.rb'

を、一応 http://localhost:3000/task/ でナニかが出ましたな。ネムいので公開したままネカせてみます。乱暴スギ。(写経とゆー事でご勘弁下さいまし)

ぢつは

ちゃんと動いてないっぽい。ってか、動作確認してません。(汗