Rubyのフレームワークであるsinatraを使う際、DBを扱う処理を再学習したのでざざっとまとめてみました。
元記事
下記エントリの転載になります。
準備
mysqlを使えるようにしておき、必要なgemも入れておきます。
$ gem install mysql2
$ gem install activerecord
# エラーが出る場合はまず下記とかを試したりする
$ sudo yum info mysql-devel
mysqlの基本的なコマンドを確認
# DB名:dbname_development
# テーブル名:items
# DBの作成
mysql> create database dbname_development;
# テーブルの作成
mysql> create table items(
-> id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> title VARCHAR(255) NOT NULL,
-> link VARCHAR(500) NOT NULL,
-> created_at DATETIME NOT NULL,
-> updated_at DATETIME NOT NULL
-> );
mysql> desc items;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | NULL | |
| link | varchar(500) | NO | | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
# カラム追加
mysql> alter table items add entrydate datetime;
# レコードの追加
mysql> insert into items
-> (title, link)
-> values
-> ("たいとる", "http://hogehogehogehoge.com");
# レコードの更新
mysql> update items set title="ほげほげ" WHERE id = 1;
# DB削除
mysql> drop database dbname_development;
# レコード削除
mysql> delete from items where id < 213;
上記コマンドを再確認しておく。
Rubyで普通にmysqlを使う
queryメソッドの中に、sqlのコマンドをそのまま書いていく感じですね。
app.rb
# アダプターに"myslq2"を使います
require 'mysql2'
# mysqlに接続
# host、username、password、データベース名を指定
client = Mysql2::Client.new(:host => "localhost", :username => "username", :password => "passwd", :database => "dbname_development")
# レコードの追加
client.query("insert into items (title, link) values ('たいとる', 'http://hogehogehogehoge.com')")
# レコードの追加(プレースホルダ)
title = "たいとる"
link = "http://hogehogehogehoge.com"
client.query("insert into items (title, link) values ('#{title}', '#{link}')")
# レコードを取得して表示
client.query("SELECT * FROM items").each do |e1|
puts e1
end
Ruby + ActiveRecord でmysqlを使ってみる
Railsでお世話になったAcriveRecordを使ってみます。
・・・その前に、DB接続情報を別ファイル化しておくと便利。
database.yml
# developmentとproductionで環境を分けて書いておくとよい?
db:
development:
adapter: mysql2
encoding: utf8
host: localhost
database: dbname_development
username: username
password: passwd
socket: /var/run/mysqld/mysqld.sock #環境によって異なる
production:
adapter: mysql2
encoding: utf8
・・・
app.rb
require 'active_record'
require 'mysql2'
# 上で作ったDB設定ファイルの読み込み
# ここではdev環境を読み込み
config = YAML.load_file('./database.yml')
ActiveRecord::Base.establish_connection(config["db"]["development"])
# モデルのクラスを宣言
class Item < ActiveRecord::Base
# バリデーションはここに記述
validates_presence_of :title
validates_presence_of :link
end
@entries #DBに登録したいデータ
@entries.each do |entry|
item = Item.new
item.title = entry.title
item.link = entry.link
# DBに保存
item.save
end
ループのINSERT処理にBULK INSERTを使う
バルクインサートするためのgem "activerecord-import" があるのでそれも使ってみます。
ループでデータを登録する時、SQL文の発行が少なくなります。詳しくは参考URLをご確認下さい。
app.rb
require 'active_record'
require 'mysql2'
# これを追加
require 'activerecord-import'
config = YAML.load_file('./database.yml')
ActiveRecord::Base.establish_connection(config["db"]["development"])
class Item < ActiveRecord::Base
validates_presence_of :title
validates_presence_of :link
end
# 配列を1個作る
insertData = []
@entries #DBに登録したいデータ
@entries.each do |entry|
item = Item.new
item.title = entry.title
item.link = entry.link
item.created_at = entry.dc_date
# 配列にpush
insertData << item
end
# importメソッドでDBに保存
Item.import insertData
ActiveRecordでリレーショナルなDBを使う
「item」と「categories」という2つの関連テーブルを作ってみます。
# itemテーブル作成
# category_id というカラムを作る
mysql> create table items(
-> id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> category_id integer default NULL,
-> created_at DATETIME NOT NULL,
-> updated_at DATETIME NOT NULL
-> );
# categoriesテーブル作成
mysql> create table categories(
-> id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> name VARCHAR(50)
-> );
app.rb
# モデルクラス Item
class Item < ActiveRecord::Base
belongs_to :category
end
# モデルクラス Category
class Category < ActiveRecord::Base
has_many :items
end
# Item belongs_to category
# category has_many items
# という関係を作る
# カテゴリオブジェクトを取得
# 今回は name が 'hogehoge'のものを取得
category = Category.where(:name => 'hogehoge').first
item = Item.new
item.category = category
# item.categoryに、取得したカテゴリのオブジェクトを指定
item.save
item.category.name # 'hogehoge'
# item.category で、関連テーブルのデータをオブジェクトとして取得できる。