狠狠撸

狠狠撸Share a Scribd company logo
O/R Mapping の話をするよ。
特に ActiveRecord の話をしたかった。
2013-10-05 第2回中国地方DB勉強会
自己紹介
?火村 智彦
?Twitter eielh
?GitHub eiel
?Facebook 本名プレイ
hiroshima.rb 会場準備係
ベストツイート
対象者
?O/RM 使っている
対象者
?O/RM 使っている
けど使ってないと主張する人
今日伝えたいこと
?O/RM 便利 手早く作るにはよい。
?使いこなしたいなら ソース読め
?データベースも勉強したほうがいい
?ActiveRecord は
?SQL を意識して書きやすくなってる
アジェンダ
? O/RM について
? 復習的な感じに
? ActiveRecord について
? 基本
? その他の機能(ざっくりと)
注意事項
?気軽にマサカリ投げましょう
?たぶん会場の偉い人が教えてくれる
?それで盛り上げてください(遠い目)
注意事項
?気軽にマサカリ投げましょう
?たぶん会場の偉い人が教えてくれる
?それで盛り上げてください(遠い目)俺がそんなにRDBに詳しいわけがない
O/RM について
7,8年前のイメージ
? 気がついたら Web業界は データベースに
データ保存するのが当たり前になっていた
? 理由とかよくわからない
? データが消えにくい
? メモリが節約できる
O/RM 以前
?SQL を文字列で構築して
?カーソル (PL/SQLとか)
?全部取得(PHPとか)
?連想配列的なものとか配列に入って返っ
てくる
O/RM 以前
?SQL を文字列で構築して
?カーソル (PL/SQLとか)
?全部取得(PHPとか)
?連想配列的なものとか配列に入って返っ
てくる
意外とめんどくさい
こんな人はいますか?
? SELECT, UPDATE は書けるけど
? INSERT は書けない
もっと楽に書きたい
だいたいデータが保存したいだけ
取り出しはみんな得意?
Object Relation Mapping
(O/RM)
O/RM
? DBに取り出した時点で
? オブジェクトになってる
? メソッド定義していけば良い
? 保存は保存メソッド呼ぶだけ
? オブジェクトを作成すれば、DBへ挿入される
トレードオフ
?DBの力を引き出しづらい
?効率の良いSQLが書きづらい
?本来データベースでできることをプロ
グラムする必要が生まれる
?関係データベースじゃなくてもよくね?
なんとなくのイメージ
PostgreSQL MySQL
なんとなくのイメージ
PostgreSQL MySQL
O/RM
なんとなくのイメージ
PostgreSQL MySQL
O/RM
NoSQL
そういえば
?WebObjects & CoreData
?すごいって聞いたけどどうなんだろう
戯言
? 関係データベースとプログラミング
? SQLは宣言的 <-> プログラミングは手続き
? SQLでも手続きは書ける (これは悪?)
? 純粋関数型言語…(宣言的)
? テーブルは集合(順番はない)
? 行は要素 -> カーソルで取得するとレコード
まとめ
?O/RM 使うと楽
?DBの力を引き出しにくい
础肠迟颈惫别搁别肠辞谤诲について
基本的な話もしますが
せっかくなので
使ってておもったことを書きます
基本的な話もしますが
せっかくなので
使ってておもったことを書きます
初心者向けの話にならないかもしれない
基本
? ルールを作ることで
? デフォルト設定ならほとんど何もいらない
? クラス名の複数形がテーブル名
? 自動的にセッタ、ゲッタが用意される
必要条件
?テーブルがある
?ActiveRecord::Base を継承したクラス
がある
?クラス名の複数形がテーブル名である
基本 例
CREATE TABLE users (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(64)
);
class User < ActiveRecord::Base
end
基本
# hoge という名前のユーザを探す。なかったら作る。
user = User.where(name: 'hoge').first_or_create
# 名前を goro に変更
user.name = 'goro'
# 変更を保存
user.save
O/RM がなかったら
# 疑似コードです。
query = "SELECT id, name FROM users WHERE name = 'hoge'"
result = SQL.execute!(query)
if result.empty?
create_query = "INSERT INTO users VALUES ('hoge')"
SQL.execute!(create_query)
result = SQL.execute!(query)
end
update_query = "UPDATE users SET name = 'goro' where id = ?"
user = result[0]
SQL.execute!(update_query, user[:id])
フォームとカラム
? テーブル設計について
? 必要なものだけ作るのが楽
? リファクタリングでカバー
? テストコードがあればどうにでもなる
? トレードオフ
? マイグレーションをがんばる
フォームとカラム
? カラムはフォームの項目に1対1に対応させると楽
? 画面をつくって入力したい項目を考えればよい
? 補佐的なカラムが必要なら追加すればいい
? 最適化が必要になったら
? その時がんばればいい
? テストコードないとつらい…
DB設計
?しっかり設計したい場合
?ActiveRecordを使わない選択
?Rail への乗り方を熟知しておく選択
phpMyAdmin病
?phpMyAdmin を使いたがる 病
?状態をみたい
?テストするのに値を書き換えたい
?rails console を生かせ
rails console を使う
? 状態をみたい
? 簡単に見えようにメソッドを用意しよう
? テストするデータつくりたい
? ファクトリメソッドを用意しよう
? テストコードかけ
rails console を使う
? 状態をみたい
? 簡単に見えようにメソッドを用意しよう
? テストするデータつくりたい
? ファクトリメソッドを用意しよう
? テストコードかけ
他の人が同じことをする時ために
手順をわかりやすくしておこう
くりかえし実行しやすくしよう
ソース読め
? 実は意外と難しくない
? ActiveRecord::Base は mixin してるだけ
? lib/active_record/base.rb
? モジュール間はほとんど直交してる
ソース読め read.rb
# 自動で定義されるゲッタの中身
# lib/active_record/attribute_methods/read.rb
# `#define_method_attribute` より
read_attribute(AttrNames::ATTR_#{safe_name}) { |n|
missing_attribute(n, caller)
}
ソース読め read.rb
? read_attribute(attr_name) で値が取れそう
? 値がなかったらなんかするっぽい
? read_attribute を見ると…
? @attributes ってところに値があるっぽい
ソース読め read.rb
? read_attribute(attr_name) で値が取れそう
? 値がなかったらなんかするっぽい
? read_attribute を見ると…
? @attributes ってところに値があるっぽい
ごめん! そんなに簡単じゃなかった!!
以下、时间が余れば
制約
? なるべく設定したい
? データの整合性が楽に保てる
? しかし
? エラーが起きたときのコードが別途必要
? エラーがSQLがわからないとわかりにくい
特に NOT NULL 制約
?基本的に自分で付ける必要がある
?できるだけかきたい
?その NULLは本当に必要なNULL?
?プログラム的には扱いにくくなる
特に外部キー制約
?複雑なシステムほどあるといい
?しかし
?テストコード書くのは大変になる
?特に実行に時間がかかる
クエリビルダ
? SQLを構築するメソッドを呼ぶと
? ActiveRecord::Relation というオブジェク
トが返ります
? これはSQLの構築の途中の状態
? to_a などを呼ぶことで SQL が実行される
クエリビルダ 例
class User < ActiveRecord::Base
scope :admin, -> { where(type: 'admin') }
scope :rank_max, -> { where(rank: 5) }
end
User.where(type: 'admin')
.to_sql # => where type = 'admin'
User.admin.to_sql # => where type = 'admin'
User.admin.rank_max.to_sql # => where type = 'admin'
# and where ranke = 5
クエリビルダ
?クエリに名前をつけて
?クエリ同士を合成できる
クエリビルダ発展
?サブクエリとしても使える
?他のテーブルの条件も使いたい
?merge メソッドで合成
その他
?もっとクエリビルダ
?リレーション
?arel
?大小比較ができない!
?squeel 使うといいよ
ご清聴ありがとうございました。

More Related Content

O/R Mapping の話をするよ。ActiveRecord の話をしたかった。