SlideShare ist ein Scribd-Unternehmen logo
1 von 32
Downloaden Sie, um offline zu lesen
named_scopeに
ついてくわしく
(株)永和システムマネジメント ¦¦ Rails勉強会@東京

 諸橋 恭介            (もろはし きょうすけ)



   k-morohashi@esm.co.jp (work)
  moronatural@gmail.com (private)
まとめ

• named_scopeを使うと、複雑な検索条
 件をシンプルかつ柔軟に記述できる

• 技術的にずいぶんおもしろい
 • とてもかっこいいmethod_missingの
  よい使い方
これはなに?

• かつてRailsには with_scope という
 APIがありました

• with_scopeを使うと、検索条件を指定
 する「スコープ」を定義できます

 • そのスコープ内での検索には、自動的
  にスコープの条件が付加されます
with_scopeの例
User.find(:all)
# SELECT * FROM users

User.find(:all, :conditions=>[“deleted=?”,false])
# SELECT * FROM users WHERE deleted = 0

User.with_scope(
  :find=>{:conditions=>[“deleted=?”,false]}) do
  User.find(:all)
end
# SELECT * FROM users WHERE deleted = 0
with_scopeについて

                Recipe 077 (p.220)

                検索条件をスコープ毎に
                まとめて定義する




http://www.amazon.co.jp/dp/4797336625
What’s
         named_scope?
•with_scopeで使っていた「検索スコー
  プ」に名前が付けられます。

•Rails 2.1の目玉機能です
 • RubyKaigi 2008でも松田さんが話しました
http://www.slideshare.net/a_matsuda/
  new-wave-of-database-programming-with-ruby-19-on-rails-21/
なにがすごいの?
•名前を付けたスコープ同士を掛け合わ
せられます。
•   DBアクセスは、 必要となった時点で賢く(多くは1回だ
    け)実行されます。


•「微妙に条件の異なる検索」の多くを
スコープの掛け合わせで表現できます
ORMとRDBMS
• RDBMSをOOPの世界に引っ張ってきた
 ORMはすごい!!

• しかしORMを使うと、RDBMSは単なる
 オブジェクトの永続化ストレージのように
 扱いがちです。

• named_scopeを使うと、RDBの集合演
 算が持つ力の一部をOOPの世界でも使える
 感じになります。
named_scopeの
     例
有効なユーザ
      users

active users
有効なユーザ
class User < ActiveRecord::Base
  named_scope(:active,
    {:condition=>["deleted = ?", false]})
end

describe “activeなユーザ” do
 it “は全員削除されて*いない*こと” do
    User.active.should be_all{|u| not u.deleted }
  end
end
人気のあるユーザ
実行時にscopeの一部を指定

     users

             hot users
人気のあるユーザ
       実行時にscopeの一部を指定

class User < ActiveRecord::Base
  named_scope :active,
   :condition=>["deleted = ?", false]

  named_scope :hot,
      Proc.new{|arg|
        {:conditions=>[“popularity > ?”, arg],
         :order =>"popularity DESC"}
    }
end
人気のあるユーザ
       実行時にscopeの一部を指定

describe “人気度80以上のユーザ” do
 before do
   @users = User.hot(80)
 end

 it "のうちトップはdahliaであること" do
    @users.first.should == users(:dahlia)
  end
end
人気かつ有効なユーザ
 crossover 2 scopes
       users

active users users
           hot
人気かつ有効なユーザ
               crossover 2 scopes
describe "BAN! dahlia" do
  before(:each) do
    # dahliaの削除フラグを立てる つまり active usersの集合から外す
    users(:dahlia).update_attribute(:deleted, true)
  end

  it "アクティブユーザで最も人気なのはcharlesであること" do
    User.active.hot(80).first.should == users(:charles)
  end

  it "クエリ発行(select_all)は一回だけ呼ばれること" do
    User.connection.should_receive(:select_all).once.and_return([])
    User.hot(80).active.find(:all)
  end
end
他にも好きな条件を
  追加できる
      users

active users n users
          hot

         Other..
named_scope
    実行時の動き
User.active.hot(80).each do |u|
  do_something
end
User.active.hot(80)
        - generate Scope instance -

User#active
#=> <#Scope:active, @proxy_scope=>User>


<#Scope:active>#hot(3)
---> <#Scope:active>#method_missing(:hot)

# scopes.include?(:hot)であるため
#=> <#Scope:hot, @proxy_scope=> <# Scope:active>>
Scope#method_missing


•User#activeはUserクラスを親ス
コープとしたScopeを作る

•Scope#method_missingは呼ばれた
メソッドに対応する子Scopeを作る
•   子Procには親スコープとしてselfを渡す
Scope#method_missing


def method_missing(method, *args, &block)
  if scopes.include?(method)
    scopes[method].call(self, *args)
  else
    with_scope :find => proxy_options do
       proxy_scope.send(method, *args, &block)
    end
  end
end
User.active.hot(80)
      - execute and respond to method -

<#Scope:hot, @proxy_scope=> <#Scope:active>>#each
---> <#Scope:hot>#proxy_found
---> <#Scope:hot>#find(:all)
---> <#Scope:hot>method_missing(:find)
---> <#Scope:hot>#with_scope{ <#Scope:active>#find }
---> <#Scope:active>#method_missing(:find)
---> <#Scope:active>#with_scope{   User.find(:all)   }
# => [<#User:..>, .... ]

[<#User:..>, ...].each{ do_something }
Scope#method_missing



•呼ばれたメソッドに対応するScope
が定義されていない場合
• 自身のfindパラメータでwith_scopeし、親ス
 コープの当該メソッドを呼び出す
Scope#method_missing


def method_missing(method, *args, &block)
  if scopes.include?(method)
    scopes[method].call(self, *args)
  else
    with_scope :find => proxy_options do
       proxy_scope.send(method, *args, &block)
    end
  end
end
with_scopeで
             書き直したイメージ
User.with_scope(
  :find=>{:conditions=>[”popularity>?”, 80],
          :order=>”popularity” }) do

  User.with_scope(
   :find=>{:conditons=>[“deleted=?”, false]}) do

   User.find(:all).each{ ... }

  end
end                    Rails2.xではこのままでは動きません
まとめ

• named_scopeを使うと、複雑な検索条
 件をシンプルかつ柔軟に記述できる

• 技術的にずいぶんおもしろい
 • とてもかっこいいmethod_missingの
  よい使い方
you.any?{|u|
  u.question?
}
FAQ: スコープはどんなふ
  うに結合されるの?
• 後ろから順にwith_scopeを使います。
 • WHERE句相当(:conditionsパラメータ)はANDで
  結合されます。

 • ORDERやLIMITは先に指定したscopeで指定して
  いるものがそのまま使われるっぽいです。

  •   この辺りのロジックは activerecord-2.1.0/lib/
      active_record/base.rb : 1807 あたりを参照
FAQ: Ruby 1.9だとより
カッコ良いという噂があるが?
 • Procオブジェクト生成に->記法が使えます
 旧
        named_scope :hot,
           Proc.new{|arg|
             {:order =>"popularity DESC",
 これが          :limit => arg}
         }

 こうなる   named_scope :hot, ->{
            {:order =>"popularity DESC",

 新       }
             :limit => arg}
FAQ: テストがよりカッコ良く
  書けるという噂があるが?
 • mockするのが楽にキレイになりそうな感じ。
 旧      User.should_receive(:find).
          with(:all,:condition=>[...]).
 これが      and_return( [alice] )


 こうなる
        User.shold_receive(:active)

 新        and_return( [alice] )
with_scopeについて

                Recipe 077 (p.220)

                検索条件をスコープ毎に
                まとめて定義する




http://www.amazon.co.jp/dp/4797336625
ご清聴
 ありがとう
ございました

Weitere ähnliche Inhalte

Was ist angesagt?

データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
Naoyuki Yamada
 
Powershell勉強会 v2 (もっと新しいバージョンがあります)
Powershell勉強会 v2 (もっと新しいバージョンがあります)Powershell勉強会 v2 (もっと新しいバージョンがあります)
Powershell勉強会 v2 (もっと新しいバージョンがあります)
Tetsu Yama
 
Powershell勉強会 v3 (もっと新しいバージョンがあります)
Powershell勉強会 v3 (もっと新しいバージョンがあります)Powershell勉強会 v3 (もっと新しいバージョンがあります)
Powershell勉強会 v3 (もっと新しいバージョンがあります)
Tetsu Yama
 
PerlとSQLのいろいろ
PerlとSQLのいろいろPerlとSQLのいろいろ
PerlとSQLのいろいろ
Takuya Tsuchida
 
Wpfと非同期
Wpfと非同期Wpfと非同期
Wpfと非同期
yone64
 

Was ist angesagt? (11)

WordPressで投稿記事情報の取得方法
WordPressで投稿記事情報の取得方法WordPressで投稿記事情報の取得方法
WordPressで投稿記事情報の取得方法
 
RailsエンジニアのためのSQLチューニング速習会
RailsエンジニアのためのSQLチューニング速習会RailsエンジニアのためのSQLチューニング速習会
RailsエンジニアのためのSQLチューニング速習会
 
Powershell勉強会 v5 (こちらが最新です。)
Powershell勉強会 v5 (こちらが最新です。)Powershell勉強会 v5 (こちらが最新です。)
Powershell勉強会 v5 (こちらが最新です。)
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 
Powershell勉強会 v2 (もっと新しいバージョンがあります)
Powershell勉強会 v2 (もっと新しいバージョンがあります)Powershell勉強会 v2 (もっと新しいバージョンがあります)
Powershell勉強会 v2 (もっと新しいバージョンがあります)
 
Teclab3
Teclab3Teclab3
Teclab3
 
Powershell勉強会 v3 (もっと新しいバージョンがあります)
Powershell勉強会 v3 (もっと新しいバージョンがあります)Powershell勉強会 v3 (もっと新しいバージョンがあります)
Powershell勉強会 v3 (もっと新しいバージョンがあります)
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
PerlとSQLのいろいろ
PerlとSQLのいろいろPerlとSQLのいろいろ
PerlとSQLのいろいろ
 
Wpfと非同期
Wpfと非同期Wpfと非同期
Wpfと非同期
 
これからのpre_get_postsの話をしよう
これからのpre_get_postsの話をしようこれからのpre_get_postsの話をしよう
これからのpre_get_postsの話をしよう
 

Ähnlich wie named_scope more detail - WebCareer

エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJS
Ayumi Goto
 
PHPフレームワーク入門
PHPフレームワーク入門PHPフレームワーク入門
PHPフレームワーク入門
Sho A
 
activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介
Kevin Toyoda
 
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみましたEucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
Etsuji Nakai
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
Masanori Kado
 
8分で分かる最近のCakePHP
8分で分かる最近のCakePHP8分で分かる最近のCakePHP
8分で分かる最近のCakePHP
Masashi Shinbara
 

Ähnlich wie named_scope more detail - WebCareer (20)

CodeIgniter入門
CodeIgniter入門CodeIgniter入門
CodeIgniter入門
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック
 
Grails 2.0.0.M1の話
Grails 2.0.0.M1の話 Grails 2.0.0.M1の話
Grails 2.0.0.M1の話
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJS
 
Elastic circle ci-co-webinar-20210127
Elastic circle ci-co-webinar-20210127Elastic circle ci-co-webinar-20210127
Elastic circle ci-co-webinar-20210127
 
PHPフレームワーク入門
PHPフレームワーク入門PHPフレームワーク入門
PHPフレームワーク入門
 
activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介
 
XPages 開発 Tips 百連発
XPages 開発 Tips 百連発XPages 開発 Tips 百連発
XPages 開発 Tips 百連発
 
脆弱性スキャナVuls(応用編)
脆弱性スキャナVuls(応用編)脆弱性スキャナVuls(応用編)
脆弱性スキャナVuls(応用編)
 
Haikara
HaikaraHaikara
Haikara
 
ZabbixのAPIを使って運用を楽しくする話
ZabbixのAPIを使って運用を楽しくする話ZabbixのAPIを使って運用を楽しくする話
ZabbixのAPIを使って運用を楽しくする話
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624
 
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみましたEucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
EucalyptusのHadoopクラスタとJaqlでBasket解析をしてHiveとの違いを味わってみました
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
 
Angular js はまりどころ
Angular js はまりどころAngular js はまりどころ
Angular js はまりどころ
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
AWS Black Belt Tech シリーズ 2015 - AWS Elastic Beanstalk
AWS Black Belt Tech シリーズ 2015 - AWS Elastic BeanstalkAWS Black Belt Tech シリーズ 2015 - AWS Elastic Beanstalk
AWS Black Belt Tech シリーズ 2015 - AWS Elastic Beanstalk
 
8分で分かる最近のCakePHP
8分で分かる最近のCakePHP8分で分かる最近のCakePHP
8分で分かる最近のCakePHP
 

Mehr von Kyosuke MOROHASHI

Test Context Arrangement Recipebook
Test Context Arrangement RecipebookTest Context Arrangement Recipebook
Test Context Arrangement Recipebook
Kyosuke MOROHASHI
 

Mehr von Kyosuke MOROHASHI (12)

Introduction HTTP via cURL
Introduction HTTP via cURLIntroduction HTTP via cURL
Introduction HTTP via cURL
 
Ruby ecosystem applied to agile project
Ruby ecosystem applied to agile projectRuby ecosystem applied to agile project
Ruby ecosystem applied to agile project
 
Test Context Arrangement Recipebook
Test Context Arrangement RecipebookTest Context Arrangement Recipebook
Test Context Arrangement Recipebook
 
Begin cucumber-in-real-world
Begin cucumber-in-real-worldBegin cucumber-in-real-world
Begin cucumber-in-real-world
 
Cucumber in Practice(en)
Cucumber in Practice(en)Cucumber in Practice(en)
Cucumber in Practice(en)
 
Rails testing environment, 2009 fall
Rails testing environment, 2009 fallRails testing environment, 2009 fall
Rails testing environment, 2009 fall
 
TDD frameworks let me dream "Project Specific Language"
TDD frameworks let me dream "Project Specific Language"TDD frameworks let me dream "Project Specific Language"
TDD frameworks let me dream "Project Specific Language"
 
Rails Tokyo 035 Cucumber
Rails Tokyo 035 CucumberRails Tokyo 035 Cucumber
Rails Tokyo 035 Cucumber
 
OSC2008 勉強会大集合 Rails勉強会@東京
OSC2008 勉強会大集合 Rails勉強会@東京OSC2008 勉強会大集合 Rails勉強会@東京
OSC2008 勉強会大集合 Rails勉強会@東京
 
Capistrano in practice - WebCareer
Capistrano in practice - WebCareerCapistrano in practice - WebCareer
Capistrano in practice - WebCareer
 
Rails <form> Chronicle
Rails <form> ChronicleRails <form> Chronicle
Rails <form> Chronicle
 
そうだ勉強会に行こう
そうだ勉強会に行こうそうだ勉強会に行こう
そうだ勉強会に行こう
 

named_scope more detail - WebCareer