なんちゃってウェブ系エンジニアの備忘録

某IT企業で働くなんちゃってウェブ系エンジニアが技術やデザインなど役に立ちそうなものなどを備忘録として載せていきます

Ruby on Railsでモデル作成からデータ取得まで実装してみる

最近Ruby on Railsを勉強し始めたばかりですが、Rails標準であるActive Recordを利用してテーブル作成からデータ取得までの流れをまとめておきます。
ちなみに、Rubyバージョン:2.0.0、Rails4.1.4、MySQL5.6系を動作させている環境を前提として進めていきます。

事前準備

RubyからMySQLへアクセスできるよう必要なパッケージをインストールしておく必要があります。

mysql2インストール
gem install mysql2
DBの作成

今回は、「sampleDb」というDBを作成します。

mysql> create database sampleDb;
アプリケーションの作成
rails new アプリ名 -d mysql

dオプションで利用するデータベースの種類を設定します。
デフォルトではSQLite3となっていますので、オプションをつけてMySQLを利用するよう設定します。

データベース接続の設定

Active Recordを利用するには、まずはconfig/database.ymlを設定する必要があります。
Railsのアプリケーションを作成すると自動的に「database.yml」ファイルが作成され、MySql用のデフォルト設定が記述されます。それを自分の環境に合わせて設定します。最低限でもMySqlへ接続するユーザーとパスワード(username、password)、利用するDB名(database)、ホスト名(host)は設定しておきましょう。

# MySQL.  Versions 5.0+ are recommended.
# (省略)
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root # MySqlへ接続するユーザー
  password: XXXX # MySqlへ接続するパスワード
  database: sampleDb # DB名
  socket: /var/lib/mysql/mysql.sock
  host: localhost # ホスト名/IPアドレス

development:
  <<: *default
  database: sampleDb

モデルクラス作成

データベースへアクセスするための肝となるモデルクラスの作成をします。
以下のコマンドよりモデルクラスを作成することが可能です。

rails generate model テーブル名 カラム名A:データ型A カラム名B:データ型B…

今回は、下記のようなシンプルな商品テーブルを作成します。

テーブル名:syohin
カラム名 データ型 概要
item string 商品名
price integer 価格
note text 説明

上記のようなテーブルを作成した場合、モデル作成コマンドは以下通りとなります。

rails generate model syohin item:string price:integer note:text

コマンド実行すると、以下のファイルが自動生成されます。
/アプリ名/db/migrate/20140812235150_create_syohins.rb
→ マイグレーションファイル。マイグレーションとは直接SQLを使わずにデータベースのテーブルやカラムなどの構造を変更できる仕組みだそうです。

/アプリ名/app/models/syohin.rb
→ syohinテーブルを操作するためのモデル本体

マイグレーションによるテーブル作成

上記、モデルクラスを作成しただけではテーブルが作成されていないので、マイグレーションによるテーブル作成を行います。

cd アプリ名
rake db:migrate 

これでsyohinテーブルが作成されました。
syohinのテーブルを確認すると、モデル設定しなかったはずのid,created_at,updated_atも作成されていることがわかります。
RailsによってDBのカラム名に「created_at」「updated_at」が自動生成されており、作成日時と更新日時を自動記録してくれるので大変便利ですね。

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| item       | varchar(255) | YES  |     | NULL    |                |
| price      | int(11)      | YES  |     | NULL    |                |
| note       | text         | YES  |     | NULL    |                |
| created_at | datetime     | YES  |     | NULL    |                |
| updated_at | datetime     | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

テストデータの投入

テーブルを作成しただけでは、何もデータが入っていない状態ですので、フィクスチャによるテストデータを投入してみたいと思います。

/アプリ名/test/fixtures配下にsyohins.ymlというファイルがあるかと思います。
中身を確認するとサンプルデータがありますが、規則性に則って5件ほどデータを追加してみます。

one:
  item: BiCジャパン ペン
  price: 500
  note: 油性ボールペンとタッチペンを1本にした便利な筆記具

two:
  item: コクヨ キャンパスノート
  price: 300
  note: 美しくまとまるキャンパスノートドット

three:
  item: コクヨ 定規
  price: 140
  note: レーザー技術を用いた目盛の加工により、見やすく正確な縮尺目盛りとなりました

four:
  item: ゼブラ サラサクリップ0.5price: 170
  note: 耐水性、耐光性に優れたゲルインクボールペン

five:
  item: サントリー 天然水
  price: 1980
  note: おいしい天然水です

six:
  item: カゴメ トマトジュース
  price: 540
  note: リコピンをはじめ、ビタミン、ミネラルなどトマトの各種成分がバランスよく含まれています

あとは以下のようにrakeコマンドを実行すると、5件のデータがsyohinテーブルに投入することができました!

rake db:fixtures:load FIXTURES=syohins

取得したデータをブラウザに表示してみる

コントローラー側
class コントローラー名 < ApplicationController
  def list
    # allメソッドで作成したテーブルをすべて取得します。
    @syohin = Syohin.all
  end
end
テンプレート側
<h1>商品リスト</h1>
<table border="1">
  <tr>
    <th>No</th>
    <th>商品名</th>
    <th>価格</th>
    <th>説明</th>
  </tr>
  <% @syohin.each.with_index(1) do |set, i| %>
  <tr>
    <td><%= "#{i}" %></td>
    <td><%= set.item %></td>
    <td><%= set.price %></td>
    <td><%= set.note %></td>
  </tr>
  <% end %>
</table>

んで、実行した結果がコチラ。
f:id:owen11:20140813125731p:plain

まとめ

著者はこれまでPHPフレームワークなどでいくつかのシステムを構築してまいりましたが、Active Recordを使えばRubyの恩恵はもちろん、SQL文を書くことなく非常に短い記述でレコードの抽出や書き換えが行えます。
シンプルでかつ簡単に実装できてしまうのが特徴ですが、複雑なクエリだとwhereで繋げたり、AND検索など実装が難しくなってくるので、この場合はRansackと組み合わせて利用したほうがよいかもしれません。
Ransackについては、時間がある際に勉強しておきたいと思います。