new wave of database programming with ruby 1.9 on rails 2.1
DESCRIPTION
LT Given at RubyKaigi 2008, describing the history of DB programming style, AR, named_scope and named_scope in Ruby 1.9 syntax.TRANSCRIPT
![Page 1: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/1.jpg)
New Wave of Database Programming with
Ruby 1.9 on Rails 2.1
松田 明 @ RubyKaigi 2008 LT
1
![Page 2: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/2.jpg)
begin
2
![Page 3: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/3.jpg)
自己紹介:名前 => 松田 明
:職業 => フリーランスの Ruby/Rails プログラマ
:仕事 => Rails
:趣味 => Rails
:仕事で書いているもの => 業務アプリが多い
3
![Page 4: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/4.jpg)
業務アプリと言えば、DB。
4
![Page 5: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/5.jpg)
人類のDBプログラミングの進化の歴史を振り返る
5
![Page 6: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/6.jpg)
WEB + DBプログラミングにおけるパラダイムの遷移
古代 → 近代 → 現代
2回ぐらいの大きなパラダイムの転換
6
![Page 7: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/7.jpg)
history
古代 → 近代 → 現代
7
![Page 8: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/8.jpg)
古代言語e.g.
P H P8
![Page 9: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/9.jpg)
:logic => 生SQLを文字列で 組み立てて発行
:view => 結果セットをぐるぐるループして HTML文字列を生成。
9
![Page 10: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/10.jpg)
サンプルコード
10
![Page 11: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/11.jpg)
省略。11
![Page 12: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/12.jpg)
古代言語の衰退に伴って 絶滅。
12
![Page 13: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/13.jpg)
history
古代 → 近代 → 現代
13
![Page 14: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/14.jpg)
大きなパラダイムの転換
14
![Page 15: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/15.jpg)
DBフレームワークの登場
• DBアクセス手段の共通化
• 設定の一元管理/コネクションのハンドリング
• RDBMS間の方言を吸収
• いわゆる O/Rマッパー
15
![Page 16: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/16.jpg)
O/Rマッパーがもたらしたもの
RDBMSと
オブジェクト指向の
幸福な出会い
16
![Page 17: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/17.jpg)
人間らしいDBプログラミング
17
![Page 18: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/18.jpg)
サンプルコード
18
![Page 19: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/19.jpg)
よくあるO/Rマッパーを使ったちょっとした業務アプリ
public interface ProductDAO { public Product find_by_id(int id); public Product find_by_name(String name); public List<Product> find_by_maker(Maker maker); public List<Product> find_by_category(Category category); public List<Product> find_by_maker_and_category(Maker maker, Category category);}
19
![Page 20: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/20.jpg)
よくあるO/Rマッパーを使ったちょっとした業務アプリ
public interface ProductDAO { public Product find_by_id(int id); public Product find_by_name(String name); public List<Product> find_by_maker(Maker maker); public List<Product> find_by_category(Category category); public List<Product> find_by_maker_and_category(Maker maker, Category category);}
Remote InterfaceImpl
EntityBeanmock Home Interface
Serializable
CORBA
RMISetter
Getter
Compile
Deploy
DBUnit
19
![Page 21: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/21.jpg)
よくあるO/Rマッパーを使ったちょっとした業務アプリ
public interface ProductDAO { public Product find_by_id(int id); public Product find_by_name(String name); public List<Product> find_by_maker(Maker maker); public List<Product> find_by_category(Category category); public List<Product> find_by_maker_and_category(Maker maker, Category category);}
Remote InterfaceImpl
EntityBeanDAO
Annotation
Dependency Injection
mock
DTODXO
Home Interface
Lazy LoadingOpen Session in View
Serializable
CORBA
RMISetter
Getter
Compile
Deploy
DBUnit
Bytecode Enhancement
19
![Page 22: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/22.jpg)
よくあるO/Rマッパーを使ったちょっとした業務アプリ
public interface ProductDAO { public Product find_by_id(int id); public Product find_by_name(String name); public List<Product> find_by_maker(Maker maker); public List<Product> find_by_category(Category category); public List<Product> find_by_maker_and_category(Maker maker, Category category);}
Remote InterfaceImpl
EntityBeanDAO
Annotation
Dependency Injection
mock
DTODXO
Home Interface
Lazy LoadingOpen Session in View
Serializable
CORBA
RMISetter
Getter
Compile
Deploy
流れるようなインターフェース(笑)
DBUnit
Bytecode Enhancement
19
![Page 23: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/23.jpg)
よくあるO/Rマッパーを使ったちょっとした業務アプリ
public interface ProductDAO { public Product find_by_id(int id); public Product find_by_name(String name); public List<Product> find_by_maker(Maker maker); public List<Product> find_by_category(Category category); public List<Product> find_by_maker_and_category(Maker maker, Category category);}
Remote InterfaceImpl
EntityBeanDAO
Annotation
Dependency Injection
mock
DTODXO
Home Interface
Lazy LoadingOpen Session in View
Serializable
CORBA
RMISetter
Getter
Compile
Deploy
流れるようなインターフェース(笑)
DBUnit
Bytecode Enhancement
XML
XML
XML
XMLXML
XML
XMLXML
XMLXML
XMLXML
XML
XMLXMLXML
XML
XML
XML
XML
19
![Page 24: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/24.jpg)
カオス(笑)
20
![Page 25: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/25.jpg)
人々がまだJavaを喋っていた時代の懐かしいお話
21
![Page 26: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/26.jpg)
history
古代 → 近代 → 現代
22
![Page 27: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/27.jpg)
次のパラダイム転換のきっかけ
23
![Page 28: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/28.jpg)
我らが ActiveRecordの登場
24
![Page 29: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/29.jpg)
•CoC をフル活用。「XML hell」と決別。
• modelクラスのアクセッサメソッドや単純な検索メソッドは DBのスキーマ定義から動的に生成。
•REST思想と見事な統合を遂げる。model == リソース。
• 柔軟なプラグイン機構
特徴
25
![Page 30: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/30.jpg)
• 言語内DSLを生かした極めて可読性の高いバリデーション
• マイグレーションも Rubyスクリプトで。
• YAML形式でさくさくテストデータを記述。テストは専用DBで。
• フィルタのようなイメージで条件を重ね合わせていくwith_scope という機能=> 「Activerecord を詳しく」by 舞波氏 参照
機能
26
![Page 31: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/31.jpg)
現代人のニーズとセンスに完璧にマッチした、変化に強い、エレガントなフレームワーク
27
![Page 32: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/32.jpg)
DB層フレームワークの決定版
28
![Page 33: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/33.jpg)
scaffoldで作る CRUDアプリ• 一覧
@models = Model.find(:all)
• 詳細@model = Model.find(params[:id])a
• 登録@model = Model.new(params[:model])@model.save
• 更新@model = Model.find(params[:id])@model.update_attributes(params[:model]
• 削除@model.destroy
29
![Page 34: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/34.jpg)
コマンド一発で自動生成
30
![Page 35: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/35.jpg)
誰でも書ける ActiveRecord
31
![Page 36: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/36.jpg)
みんなの ActiveRecord
32
![Page 37: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/37.jpg)
ご清聴ありが(ry
33
![Page 38: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/38.jpg)
「15分で作るブログ」みたいなアプリ
ならね。
34
![Page 39: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/39.jpg)
user_values = [] user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged? if project user_values += project.users.sort.collect{|s| [s.name, s.id.to_s] } else # members of the user's projects user_values += User.current.projects.collect(&:users).flatten.uniq.sort.collect{|s| [s.name, s.id.to_s] } end @available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } unless user_values.empty? @available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
if project # project specific filters @available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } } @available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } } unless @project.active_children.empty? @available_filters["subproject_id"] = { :type => :list_subprojects, :order => 13, :values => @project.active_children.collect{|s| [s.name, s.id.to_s] } } end @project.all_custom_fields.select(&:is_filter?).each do |field| case field.field_format when "text" options = { :type => :text, :order => 20 } when "list" options = { :type => :list_optional, :values => field.possible_values, :order => 20} when "date" options = { :type => :date, :order => 20 } when "bool" options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 } else options = { :type => :string, :order => 20 } end @available_filters["cf_#{field.id}"] = options.merge({ :name => field.name }) end # remove category filter if no category defined @available_filters.delete "category_id" if @available_filters["category_id"][:values].empty? end
でも実際の業務アプリになると…
35
![Page 40: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/40.jpg)
やっぱりカオス・・・
36
![Page 41: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/41.jpg)
実は DBアクセスは Railsの弱点
• 結局、SQL文字列を組み立てる処理を常に意識
•CoCではどうにもならない泥臭いところ
• 複雑になればなるほど肥大化
37
![Page 42: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/42.jpg)
• 「SQLの文字列を組み立てる」
という昔ながらのダサい処理
•Ruby的オブジェクト指向
というハイセンスで華やかな世界観
この問題の根本原因
38
![Page 43: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/43.jpg)
• 「SQLの文字列を組み立てる」
という昔ながらのダサい処理
•Ruby的オブジェクト指向
というハイセンスで華やかな世界観
この問題の根本原因
大きなギャップ
38
![Page 44: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/44.jpg)
RDBMS操作 == SQL文を組み立てて発行することという先入観から脱却できていないから。
why?
39
![Page 45: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/45.jpg)
RDBMS操作 != SQL文を組み立てて発行すること
actually,
40
![Page 46: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/46.jpg)
DB操作の本質は集合演算。
41
![Page 47: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/47.jpg)
そこで、
42
![Page 48: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/48.jpg)
history
古代 → 近代 → 現代 → 2008年~
43
![Page 49: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/49.jpg)
named_scope
44
![Page 50: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/50.jpg)
named_scope とは?
• もともとは 昨秋ごろに彗星のように登場した has_finderという名前の野良 Railsプラグイン
• 今年の3月ごろ、Rails 2.1系 から正式に
Rails本体に取り込まれた
45
![Page 51: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/51.jpg)
named_scopeの機能• 問い合わせを固まりではなく断片でとらえる
「scope」
• 「scope」に名前を付けて、DSL的にあらかじめ定義
• 複雑な条件クエリの組み立ては、定義済みの「scope」を組み合わせて動的に作ることで表現できる
46
![Page 52: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/52.jpg)
example• modelnamed_scope :of_the_month, :conditions => {:reported_at => Date.today.beginning_of_month..Date.today.end_of_month}
• 呼び出し側@reports = Report.of_the_month
• 発行されるSQLSELECT * FROM "reports" WHERE ("reports"."reported_at" BETWEEN '2008-06-01' AND '2008-06-30')
47
![Page 53: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/53.jpg)
『DAO』と何が違うの?
48
![Page 54: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/54.jpg)
example(2)• modelnamed_scope :of_the_month, :conditions => {:reported_at => Date.today.beginning_of_month..Date.today.end_of_month} named_scope :written_by, Proc.new {|u| {:conditions => {:user_id => u}}}
• 呼び出し側@reports = Report.of_the_month.written_by(@current_user)
• 発行されるSQLSELECT * FROM "reports" WHERE (("reports"."user_id" = 1) AND ("reports"."reported_at" BETWEEN '2008-06-01' AND '2008-06-30'))
49
![Page 55: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/55.jpg)
カスケードして呼び出してもSQLは1回
50
![Page 56: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/56.jpg)
可読性高すぎ。
51
![Page 57: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/57.jpg)
イメージ図
52
![Page 58: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/58.jpg)
イメージ図of_the_month
52
![Page 59: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/59.jpg)
イメージ図of_the_month written_by
52
![Page 60: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/60.jpg)
イメージ図of_the_month written_by
これを select。
52
![Page 61: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/61.jpg)
まさに集合演算。
53
![Page 62: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/62.jpg)
集合がDSLで!
54
![Page 63: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/63.jpg)
named_scopeがもたらしたものRDBMS
と
オブジェクト指向と
集合演算の
幸福な出会い55
![Page 64: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/64.jpg)
これを実現している技術
• scopeの実体は Procのインスタンス
• チェインされた Procたちをまとめて評価 -> 実行
• Rubyの豊かな表現力を生かした、Rubyならではの実装
56
![Page 65: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/65.jpg)
単体テストも楽々(RSpecの場合)• scopeそのものの条件テスト
describe 'written_by' do it 'Userのインスタンスを受け取って user_id で検索を実行すること' do Report.written_by(@user).proxy_options.should == {:conditions => {:user_id => 1}} end
• ロジック側から然るべきscopeが正しく呼ばれていることのテスト it ‘named_scope :written_by を「ログインユーザ」を引数にして呼び出していること’ do @written_by_scope.should_receive(:call).with(Report, users(:ito)).and_return(Report) do_get end
57
![Page 66: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/66.jpg)
Rails 2.2に向けてますます機能拡張中!
• !付きメソッド
• 検索以外でも使えるように
• 詳細は
Rails勉強会@東京ブースにて配布中のペーパー参照。
58
![Page 67: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/67.jpg)
Life Changing!
59
![Page 68: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/68.jpg)
まとめ
60
![Page 69: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/69.jpg)
RubyプログラマはRubyでものを考える
61
![Page 70: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/70.jpg)
named_scopeは、泥臭い DB操作をキレイな Ruby語に翻訳するデバイス
62
![Page 71: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/71.jpg)
でも、キレイな Ruby語とか言うわりには、
• デフォルト引数を与えたい場合、こう書きたいけど書けないnamed_scope :recent, Proc.new {|time || 2.weeks.ago| {:conditions => ['reported_at > ?', time]} }
• ので、こんなふうにでも書いて逃げるしか。named_scope :recent, Proc.new {|*args| {:conditions => ['reported_at > ?', (args.first || 2.weeks.ago)]} }
63
![Page 72: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/72.jpg)
これはちょっとイケてないかも?
64
![Page 73: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/73.jpg)
そこで、Ruby 1.9。
65
![Page 74: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/74.jpg)
remember this?66
![Page 75: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/75.jpg)
Ruby 1.9なら
•新しい lambda記法 -> ができた
•procにデフォルト引数がとれるようになった
67
![Page 76: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/76.jpg)
Ruby 1.9 なら• さっきのこれが、
named_scope :recent, Proc.new {|*args| {:conditions => ['reported_at > ?', (args.first || 2.weeks.ago)]} }
• こうなる。named_scope :recent, ->(time = 2.weeks.ago) { {:conditions => ["reported_at > ?", time]} }
68
![Page 77: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/77.jpg)
Ruby 1.9 is for you, Railers!
69
![Page 78: New Wave of Database Programming with Ruby 1.9 on Rails 2.1](https://reader033.vdocument.in/reader033/viewer/2022052901/55669663d8b42a78708b4e68/html5/thumbnails/78.jpg)
end
70