Rubyのフレームワークである”sinatra”を使う際、DBを扱う処理を再学習したのでざざっとまとめてみました。
mysqlを使えるようにしておき、必要なgemも入れておきます。
$ gem install mysql2 $ gem install activerecord #エラーが出る場合はまず下記とかを試したりする $ sudo yum info mysql-devel
# 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, description, category) -> values -> ("たいとる", "http://hogehogehogehoge.com", "ほげほげディスクリプション", "hatena"); # レコードの更新 mysql> update items set title="ほげほげ" WHERE id = 1; # DB削除 mysql> drop database dbname_development; # レコード削除 mysql> delete from items where id < 213;
上記コマンドを再確認しておく。
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
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
バルクインサートするための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
「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 で、関連テーブルのデータをオブジェクトとして取得できる。
これまでRailsで楽してたので、いざRubyで組もうと思ったらいろいろ忘れてました。Railsに任せっきりはやはり駄目ですね。特にActiveRecordぱっかり使ってるとSQL文が特に・・・でも楽なんだよなぁ。
次はSinatraの使い方をざっくりまとめます。
(追記)
→ Sinatraの記事はこちら