Ruby on Rails バージョン 3 を使ってみる.
【関係するディレクトリとファイル(主要なもの)】
【この Web ページで行うこと】
データベース管理システムソフトウェアとして SQLite バージョン 3を使うとき
cd <全体のルートディレクトリ> rails new hoge --database sqlite3
gem 'execjs' gem 'therubyracer'
cd hoge rails generate controller welcome index
rm public/index.html
元々の config/routes.rb の記述に従って編集する。
■ パターン1
root 'welcome#index'
■ パターン2
root :to => 'welcome#index'
cd hoge rails generate scaffold order_record year:integer month:integer day:integer customer_name:text product_name:text unit_price:float qty:integer created_at:timestamp updated_at:timestamp
ファイル cc/migrate/<タイムスタンプ>_create_order_records.rb を編集する
■ SQLite 3 でのマイグレーション・ファイルの設定例:
class CreateOrderRecords < ActiveRecord::Migration def change create_table :order_records do |t| t.integer :year, :null => false t.integer :month, :null => false t.integer :day, :null => false t.text :customer_name, :null => false t.text :product_name, :null => false t.float :unit_price, :null => false t.integer :qty, :null => false, :default => 1 t.timestamp :created_at, :null => false t.timestamp :updated_at t.timestamps end end end
■ SQLite 3 以外でのマイグレーション・ファイルの設定例:
class CreateOrderRecords < ActiveRecord::Migration def change create_table :order_records do |t| t.integer :year, :null => false t.integer :month, :null => false t.integer :day, :null => false t.text :customer_name, :null => false t.text :product_name, :null => false t.float :unit_price, :null => false t.integer :qty, :null => false, :default => 1 t.timestamp :created_at, :null => false t.timestamp :updated_at t.timestamps end #add constraints execute "ALTER TABLE order_records ADD CONSTRAINT c1_order_records CHECK ( year > 2008 );" execute "ALTER TABLE order_records ADD CONSTRAINT c2_order_records CHECK ( month >= 1 AND month <= 12 );" execute "ALTER TABLE order_records ADD CONSTRAINT c3_order_records CHECK ( day >= 1 AND day <= 31 );" execute "ALTER TABLE order_records ADD CONSTRAINT c4_order_records CHECK ( unit_price > 0 );" execute "ALTER TABLE order_records ADD CONSTRAINT c5_order_records CHECK ( qty > 0 );" execute "ALTER TABLE order_records ADD CONSTRAINT c6_order_records CHECK ( ( unit_price * qty ) < 200000 );" end end
rake db:create:all rake db:migrate
rails server
http://localhost:3000/order_records
[このページで説明している.こと]
※ この Web ページの手順をなぞる場合は,sqlite3 パッケージのインストールも済んでいること
gem install rails gem install thin gem install exexjs gem install therubyracer gem install sqlite3
mysql, postgresql, sqlite3, oracle などが指定できる.
ここでは Ruby on Rails の学習を行いたいので,SQLite バージョン 3を使うことにする. Ruby から SQLite 3のデータベースを扱うようなプログラムの作成については, 別の Web ページで詳しく説明している.
実際に使うには,データベースの権限の設定,複数のアプリケーションプログラムでのデータベースの共有を行うでしょうから, SQLite ではなく,MySQL の利用 等を使うことを検討してください.
■ rails バージョン 3 の場合の例
cd <全体のルートディレクトリ> rails new hoge --database sqlite3
なお、データベース管理システムソフトウェアとして MySQL の利用 を使うときは、次のように操作する
cd <全体のルートディレクトリ> rails new hoge --database mysql
※ rails バージョン 2 系列 の場合の例
cd <全体のルートディレクトリ> rails hoge --database sqlite3
既定(デフォルト)では,SQLite 3 が使われることが確認できる. この Web ページの目的である Ruby on Rails の入門用)としては全く問題ない.
データベース名も確認できる.
※ MySQL などを使うときは,database.yml にパスワードを設定する
■ Linux での実行例
cd hoge more config/database.yml
■ Windows の場合には「/」を「\」に読み替えて下さい.
cd hoge more config\database.yml
Rails サーバを起動し、動作を確認する
cd hoge rails server
http://localhost:3000
Rails サーバを起動した端末で「コントロールキー」と「c」の同時押し
cd hoge rails generate controller welcome index
元々の config/routes.rb の記述に従って編集する。
■ パターン1
cd hoge root 'welcome#index'
■ パターン2
cd hoge root :to=>'welcome#index'
「rake routes」で確認する.
rake routes
このページでは,次のテーブル定義を使う.
■ SQLite 3 の場合:
create table order_records ( id INTEGER PRIMARY KEY autoincrement not null, year INTEGER not null, month INTEGER not null, day INTEGER not null, customer_name text not null, product_name text not null, unit_price REAL not null, qty INTEGER not null DEFAULT 1, created_at DATETIME not null, updated_at DATETIME not null );
■ SQLite 3以外 の場合:
create table order_records ( id INTEGER PRIMARY KEY autoincrement not null, year INTEGER not null CHECK ( year > 2008 ), month INTEGER not null CHECK ( month >= 1 AND month <= 12 ), day INTEGER not null CHECK ( day >= 1 AND day <= 31 ), customer_name text not null, product_name text not null, unit_price REAL not null CHECK ( unit_price > 0 ), qty INTEGER not null DEFAULT 1 CHECK ( qty > 0 ), created_at DATETIME not null, updated_at DATETIME not null, CHECK ( ( unit_price * qty ) < 200000 ) );
cd hoge
実行例
bundle install
rails generate scaffold order_record year:integer month:integer day:integer customer_name:text product_name:text unit_price:float qty:integer created_at:timestamp updated_at:timestamp
【ここで試している設定の要点】
Rails で使えるデータ型は次の通り
データ型の詳細については,別の Web ページで説明する.
※ execjs を使っている場合,次のようなエラーが出る場合があります.このときは、node.js などをインストールすることで回避できる場合があります. 詳しくは、 https://github.com/sstephenson/execjs
※ Windows の場合には「/」を「\」に読み替えて下さい.
Windows で「sqlite3.dll が無いよ」というエラーが出た場合には SQLite 3のサイト から sqlite3.dll をダウンロードして,C:\Windows\System32 に置く
rake routes
マイグレーション定義ファイルには,データベースのテーブル定義と一貫性制約の記述等を行う.
【外部ページへのリンク】
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html
マイグレーション・ファイルを表示させる手順の例は次の通り.20110901074423 は実際の日付に読み替えてください.
■ Linux での実行例
more cc/migrate/20110901074423_create_order_records.rb
※ Windows の場合には「/」を「\」に読み替えて下さい.
いま確認したマイグレーション・ファイルを書き換えて,一貫性制約を記述したい.
記述したい一貫性制約は,SQL を使って次のように書くことができるとする.問題は,これを,マイグレーション・ファイルにどう書くか,ということ.
※ SQL の文法と意味については,ここでは説明しないので, 別の Web ページを見てください.
◆ 一貫性制約を含むテーブル定義の例 (SQL での記述)
このページでは,次のテーブル定義を使う.
■ SQLite 3 の場合:
create table order_records ( id INTEGER PRIMARY KEY autoincrement not null, year INTEGER not null, month INTEGER not null, day INTEGER not null, customer_name text not null, product_name text not null, unit_price REAL not null, qty INTEGER not null DEFAULT 1, created_at DATETIME not null, updated_at DATETIME not null);
■ SQLite 3以外 の場合:
create table order_records ( id INTEGER PRIMARY KEY autoincrement not null, year INTEGER not null CHECK ( year > 2008 ), month INTEGER not null CHECK ( month >= 1 AND month <= 12 ), day INTEGER not null CHECK ( day >= 1 AND day <= 31 ), customer_name text not null, product_name text not null, unit_price REAL not null CHECK ( unit_price > 0 ), qty INTEGER not null DEFAULT 1 CHECK ( qty > 0 ), created_at DATETIME not null, updated_at DATETIME not null, CHECK ( ( unit_price * qty ) < 200000 ) );
◆ ここで行うこと: 上記のテーブル定義と等価なものをマイグレーション・ファイルに記述したいということ
SQL の not null は非空制約であり, SQL の DEFAULT はデフォルト値 (default value) の指定である.
「ActiveRecord::ConnectionAdapters::TableDefinition#column」の記述によれば,
デフォルト値を SQL の「NULL」にしたい場合には,マイグレーション・ファイルでは 「:default => nil」のように書く
UNIQUE は一意制約であり, CHECK (...) は更新時にチェックされる式 であり, REFERENCES は参照整合性制約である.
◆ SQLite 3 でのマイグレーション・ファイルの設定例:
class CreateOrderRecords < ActiveRecord::Migration def change create_table :order_records do |t| t.integer :year, :null => false t.integer :month, :null => false t.integer :day, :null => false t.text :customer_name, :null => false t.text :product_name, :null => false t.float :unit_price, :null => false t.integer :qty, :null => false, :default => 1 t.timestamp :created_at, :null => false t.timestamp :updated_at t.timestamps end end end
◆ SQLite 3 以外でのマイグレーション・ファイルの設定例:
http://guides.rails.info/migrations.html の記述によれば, マイグレーション・ファイル内に execute ... を含めることになる.実例を下に載せています.
SQLite 3 には ADD CONSTRAINT の機能が実装されていないため、下のプログラムは動かない(2011/09/01 時点).
class CreateOrderRecords < ActiveRecord::Migration def change create_table :order_records do |t| t.integer :year, :null => false t.integer :month, :null => false t.integer :day, :null => false t.text :customer_name, :null => false t.text :product_name, :null => false t.float :unit_price, :null => false t.integer :qty, :null => false, :default => 1 t.timestamp :created_at, :null => false t.timestamp :updated_at t.timestamps end #add constraints execute "ALTER TABLE order_records ADD CONSTRAINT c1_order_records CHECK ( year > 2008 );" execute "ALTER TABLE order_records ADD CONSTRAINT c2_order_records CHECK ( month >= 1 AND month <= 12 );" execute "ALTER TABLE order_records ADD CONSTRAINT c3_order_records CHECK ( day >= 1 AND day <= 31 );" execute "ALTER TABLE order_records ADD CONSTRAINT c4_order_records CHECK ( unit_price > 0 );" execute "ALTER TABLE order_records ADD CONSTRAINT c5_order_records CHECK ( qty > 0 );" execute "ALTER TABLE order_records ADD CONSTRAINT c6_order_records CHECK ( ( unit_price * qty ) < 200000 );" end end
cd hoge
rake -T
rake db:version
「UTF-8」のように表示される.
rake db:charset
Ruby が認識するキャラクタコードの設定は、config/environment.rb で「$KCODE = 'u'」のように行う.
rake db:create:all
メッセージから,新しいテーブルが定義されたことが分かります.
rake db:migrate
「"id" integer primary key autoincrement not null」が増えていることなどが確認できる.
echo "select * from sqlite_master;" | sqlite3 db/development.sqlite3
cd hoge
rails server
■ Windows の場合には「/」を「\」に読み替えて下さい.
WEBrick が起動していることが確認できる.ポート番号が 3000 であることも確認できる.
Web ブラウザで http://127.0.0.1:3000 を指定します.
この Web ページの「コントローラの作成」の手順を踏んでいた場合には, Rails サーバと通信して,welcome/index.html.erb が次のように表示される
※ Windows のファイヤウオール機能により,ポート番号 3000 との通信が遮断されている場合があるので, ポート番号 3000 の通信については解除しておくこと.
Ctrl + 「c」(コントロールキーと「c」キーの同時押し)で,Rails サーバが終了します.
■ Windows の場合には「/」を「\」に読み替えて下さい.
以下の手順では,いま生成された scaffold アプリケーションを使ってみる.
※ もし,どれかのフィールドのデータが空 (NULL) のままだと,テーブル定義で指定した not null 制約に違反し,行(レコード)を挿入できない.
◆ 間違いがあるときは「Edit」で編集画面に戻る.
◆ これで正しいときは「Back」で元の画面に戻る.
# 「① ② I Ⅱ ㍉ ㌢ ㈱」は Shift_JIS にはなく,Shift_JIS を拡張した文字コードセットにある # 「‖ 〜 − ¢ £ ¬」は Shift_JIS, EUC-JP, ISO-2022-JP では同じ文字コードなのに Windows-31J では違う文字コード # 「表 十 構」は、Shift_JIS では 2 バイト目が「5C」になっているもの # その他 "〒" ハンカクカナ