Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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について
基本的な話もしますが
せっかくなので
使ってておもったことを書きます
基本的な話もしますが
せっかくなので
使ってておもったことを書きます
初心者向けの話にならないかもしれない
基本
• ルールを作ることで
• デフォルト設定ならほとんど何もいらない
• クラス名の複数形がテーブル名
• 自動的にセッタ、ゲッタが用意される
必要条件
•テーブルがある
•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'
# 変更を保存
...
O/RM がなかったら
# 疑似コードです。
query = "SELECT id, name FROM users WHERE name = 'hoge'"
result = SQL.execute!(query)
if result.emp...
フォームとカラム
• テーブル設計について
• 必要なものだけ作るのが楽
• リファクタリングでカバー
• テストコードがあればどうにでもなる
• トレードオフ
• マイグレーションをがんばる
フォームとカラム
• カラムはフォームの項目に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_attribut...
ソース読め 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) }
...
クエリビルダ
•クエリに名前をつけて
•クエリ同士を合成できる
クエリビルダ発展
•サブクエリとしても使える
•他のテーブルの条件も使いたい
•merge メソッドで合成
その他
•もっとクエリビルダ
•リレーション
•arel
•大小比較ができない!
•squeel 使うといいよ
ご清聴ありがとうございました。
Upcoming SlideShare
Loading in …5
×

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

6,914 views

Published on

第二回 中国地方DB勉強会
http://local.aguuu.com/events/21550

O/R Mapping と ActiveRecord の話をする予定だったけど、時間が短くなったので、ActiveRecord の話はざっくりとなったセッションです。

Published in: Technology

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

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

×