SlideShare uma empresa Scribd logo
1 de 18
Baixar para ler offline
Model.search
    Tse-Ching Ho
     2010-04-25
Ruby Conf Taiwan 2010
ActiveRecord
ActiveRecord v.s. Arel
module ActiveRecord
 class Base
  class < self
    def unscoped
     @unscoped ||= Relation.new(self, arel_table)
     finder_needs_type_condition? ? @unscoped.where(type_condition) : @unscoped
    end
    def arel_table
     @arel_table ||= Arel::Table.new(table_name, :engine => arel_engine)
    end
  end
 end
end
module ActiveRecord::NamedScope::ClassMethods
 def scoped(options = {}, &block)
  if options.present?
    relation = scoped.apply_finder_options(options)
    block_given? ? relation.extending(Module.new(&block)) : relation
  else
    current_scoped_methods ? unscoped.merge(current_scoped_methods) :
unscoped.clone
  end
 end
end
Scope with Arel
class Product < ActiveRecord::Base
 scope :name_like, lambda { |param|
   where(self.arel_table[:name].matches("%#{param}%"))
 }
 scope :attr_like, lambda { |attr, param|
   where(self.arel_table[attr].matches("%#{param}%"))
 }
 scope :attr_gt, lambda { |attr, param|
   where(self.arel_table[attr].gt(param))
 }
end
Product.name_like('Ruby')
Product.attr_like(:name, 'Ruby')
   SELECT "products".* FROM "products"
   WHERE ("products"."name" LIKE '%Ruby%')
Product.attr_gt(:price, 100)
   SELECT "products".* FROM "products"
   WHERE ("products"."price" > 100)
AREL
Match => LIKE

NotMatch => NOT LIKE
NotMatch ?
products = Product.scoped
puts products.where(products.table[:name].matches('%Ruby%')).to_sql
  SELECT "products".* FROM "products"
  WHERE ("products"."name" LIKE '%Ruby%')

products = Product.scoped
puts products.where(%Q{"products"."name" NOT LIKE '%Ruby%'}).to_sql
puts products.where(%Q{"products"."name" NOT LIKE ?}, '%Ruby%').to_sql
  SELECT "products".* FROM "products"
  WHERE ("products"."name" NOT LIKE '%Ruby%')

products = Product.scoped
products.where(products.table[:name].notmatches('%Ruby%'))

products = Product.search
products.name_not_like = 'Ruby'

products = Product.search('name_not_like' => 'Ruby')
NotMatch !
require 'arel'
# lib/arel/algebra/predicates.rb
module Arel::Predicates
 class NotMatch < Binary; end
end
# lib/arel/algebra/attributes/attribute.rb
module Arel
 class Attribute
  def notmatches(regexp); Predicates::NotMatch.new(self, regexp) end
 end
end
# lib/arel/engines/sql/predicates.rb
module Arel::Predicates
 class NotMatch < Binary
  def predicate_sql; 'NOT LIKE' end
 end
end
# lib/arel/engines/memory/predicates.rb
module Arel::Predicates
 class NotMatch < Binary
  def operator; :"!~" end
 end
end
Rails 2.3 => Search Logic

Rails 3 => Search Logic
Write Your Own
Search Method !!!
Meta Search
http://github.com/ernie/meta_search
MetaSearch::Searches::Base



module MetaSearch::Searches::Base
 def search(opts = {})
  search_options = opts.delete(:search_options) || {}
  builder = MetaSearch::Builder.new(self, search_options)
  builder.build(opts)
 end
end
ActiveRecord::Base.send :include, MetaSearch::Searches::ActiveRecord


               Product.search('name_not_like' => 'Ruby')
MetaSearch::Builder
module MetaSearch
 class Builder
  attr_reader :base, :relation, :join_dependency
  delegate :joins, :includes, :all, :count, :to_sql, :paginate, :find_each,
            :first, :last, :each, :to => :relation
  def initialize(base, opts = {})
    @base = base
    @associations = {}
    @join_dependency =
ActiveRecord::Associations::ClassMethods::JoinDependency.new(@base, [],
nil)
    @relation = @base.scoped
  end
  def build(opts)
    @relation = @base.scoped
    opts.each_pair {|k, v| self.send("#{k}=", v)}
    self
  end                                      name_not_like=
 end
end
MetaSearch::Builder
module MetaSearch               name_not_like=
 class Builder
  def method_missing(method_id, *args, &block)
   if match = matches_attribute_method(method_id)
     condition, attribute, association = match.captures.reverse
     build_method(association, attribute, condition)
     self.send(preferred_method_name(method_id), *args)
   elsif match = matches_where_method(method_id)
     condition = match.captures.first
     build_where_method(condition, Where.new(condition))
     self.send(method_id, *args)
   else
      super      @relation.where(products.table[:name]
   end           .notmatches('%Ruby%')
  end
 end
end
MetaSearch::Where
MetaSearch::Where.add(['not_like', 'not_contain', 'notmatches', {
    :types => [:string, :text, :binary],
    :condition => :notmatches,           Arel:: Attribute#notmatches
    :formatter => '"%#{param}%"'
}])
@@wheres['not_like'] = {
  :name => 'not_like',
  :aliases => ['not_contain', 'notmatches'],
  :types => [:string, :text, :binary],
  :condition => :notmatches,
  :formatter => Proc.new {|param| eval '"%#{param}%"'},
  :validator => Proc.new {|param| !param.blank?},
  :splat_param => false
}
#=> Where.new(@@wheres['not_like'])

Where.new('not_like') == Where.get('not_like') # if new with string
More Possibilities ?

Article.where(:created_at > 100.days.ago, :title =~ 'Hi%').to_sql
 SELECT "articles".* FROM "articles"
 WHERE ("articles"."created_at" > '2010-01-05 20:11:44.997446')
 AND ("articles"."title" LIKE 'Hi%')




http://gist.github.com/265308
http://github.com/ernie/meta_where
About Me


  Tse-Ching Ho
http://github.com/tsechingho



   http://grassbrook.com
END

Mais conteúdo relacionado

Mais procurados

ALPHA Script - XML Model
ALPHA Script - XML ModelALPHA Script - XML Model
ALPHA Script - XML ModelPROBOTEK
 
Introduction to PHP Lecture 1
Introduction to PHP Lecture 1Introduction to PHP Lecture 1
Introduction to PHP Lecture 1Ajay Khatri
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby MetaprogrammingNando Vieira
 
Learn You a Functional JavaScript for Great Good
Learn You a Functional JavaScript for Great GoodLearn You a Functional JavaScript for Great Good
Learn You a Functional JavaScript for Great GoodMike Harris
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of JavascriptTarek Yehia
 
JavaScript - Chapter 6 - Basic Functions
 JavaScript - Chapter 6 - Basic Functions JavaScript - Chapter 6 - Basic Functions
JavaScript - Chapter 6 - Basic FunctionsWebStackAcademy
 
Types End-to-End @ samsara
Types End-to-End @ samsaraTypes End-to-End @ samsara
Types End-to-End @ samsaraStephen Wan
 
Omnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsOmnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsJustin Edelson
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSVisual Engineering
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogrammingjoshbuddy
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecordscalaconfjp
 
JavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UXJavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UXJWORKS powered by Ordina
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Aaron Gustafson
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupHenrik Engström
 
ERRest: the Basics
ERRest: the BasicsERRest: the Basics
ERRest: the BasicsWO Community
 

Mais procurados (20)

ALPHA Script - XML Model
ALPHA Script - XML ModelALPHA Script - XML Model
ALPHA Script - XML Model
 
Introduction to PHP Lecture 1
Introduction to PHP Lecture 1Introduction to PHP Lecture 1
Introduction to PHP Lecture 1
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby Metaprogramming
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
 
Learn You a Functional JavaScript for Great Good
Learn You a Functional JavaScript for Great GoodLearn You a Functional JavaScript for Great Good
Learn You a Functional JavaScript for Great Good
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 
Jsp And Jdbc
Jsp And JdbcJsp And Jdbc
Jsp And Jdbc
 
JavaScript - Chapter 6 - Basic Functions
 JavaScript - Chapter 6 - Basic Functions JavaScript - Chapter 6 - Basic Functions
JavaScript - Chapter 6 - Basic Functions
 
Types End-to-End @ samsara
Types End-to-End @ samsaraTypes End-to-End @ samsara
Types End-to-End @ samsara
 
Omnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsOmnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the Things
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJS
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecord
 
jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
 
Jquery 4
Jquery 4Jquery 4
Jquery 4
 
JavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UXJavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UX
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 
PHP array 2
PHP array 2PHP array 2
PHP array 2
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
ERRest: the Basics
ERRest: the BasicsERRest: the Basics
ERRest: the Basics
 

Semelhante a model.search: customize your own search logic

Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Template rendering in rails
Template rendering in rails Template rendering in rails
Template rendering in rails Hung Wu Lo
 
TDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyTDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyFabio Akita
 
Documenting from the Trenches
Documenting from the TrenchesDocumenting from the Trenches
Documenting from the TrenchesXavier Noria
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Introzhang tao
 
jQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends ForeverjQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends Foreverstephskardal
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2RORLAB
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
Rails Plugin Development 101 (...and some...)
Rails Plugin Development 101 (...and some...)Rails Plugin Development 101 (...and some...)
Rails Plugin Development 101 (...and some...)Jim Myhrberg
 

Semelhante a model.search: customize your own search logic (20)

Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Template rendering in rails
Template rendering in rails Template rendering in rails
Template rendering in rails
 
TDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyTDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em Ruby
 
Documenting from the Trenches
Documenting from the TrenchesDocumenting from the Trenches
Documenting from the Trenches
 
Dsl
DslDsl
Dsl
 
Intro to Rails 4
Intro to Rails 4Intro to Rails 4
Intro to Rails 4
 
Elegant APIs
Elegant APIsElegant APIs
Elegant APIs
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Rails 3 hints
Rails 3 hintsRails 3 hints
Rails 3 hints
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
jQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends ForeverjQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends Forever
 
Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Fewd week6 slides
Fewd week6 slidesFewd week6 slides
Fewd week6 slides
 
Oracle adapters for Ruby ORMs
Oracle adapters for Ruby ORMsOracle adapters for Ruby ORMs
Oracle adapters for Ruby ORMs
 
Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
Rails Plugin Development 101 (...and some...)
Rails Plugin Development 101 (...and some...)Rails Plugin Development 101 (...and some...)
Rails Plugin Development 101 (...and some...)
 

Mais de Tse-Ching Ho

20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_twTse-Ching Ho
 
Ruby on bioinformatics
Ruby on bioinformaticsRuby on bioinformatics
Ruby on bioinformaticsTse-Ching Ho
 
Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsTse-Ching Ho
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introductionTse-Ching Ho
 
devise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwandevise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwanTse-Ching Ho
 
Rails-3-app-auto-generator-20100817
Rails-3-app-auto-generator-20100817Rails-3-app-auto-generator-20100817
Rails-3-app-auto-generator-20100817Tse-Ching Ho
 
The Power of Rails 2.3 Engines & Templates
The Power of Rails 2.3 Engines & TemplatesThe Power of Rails 2.3 Engines & Templates
The Power of Rails 2.3 Engines & TemplatesTse-Ching Ho
 

Mais de Tse-Ching Ho (9)

20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_tw
 
Ruby on bioinformatics
Ruby on bioinformaticsRuby on bioinformatics
Ruby on bioinformatics
 
Webconf2013
Webconf2013Webconf2013
Webconf2013
 
Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in rails
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
 
devise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwandevise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwan
 
Rails-3-app-auto-generator-20100817
Rails-3-app-auto-generator-20100817Rails-3-app-auto-generator-20100817
Rails-3-app-auto-generator-20100817
 
The Power of Rails 2.3 Engines & Templates
The Power of Rails 2.3 Engines & TemplatesThe Power of Rails 2.3 Engines & Templates
The Power of Rails 2.3 Engines & Templates
 
ruby e-commerce
ruby e-commerceruby e-commerce
ruby e-commerce
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 

Último (20)

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 

model.search: customize your own search logic

  • 1. Model.search Tse-Ching Ho 2010-04-25 Ruby Conf Taiwan 2010
  • 3. ActiveRecord v.s. Arel module ActiveRecord class Base class < self def unscoped @unscoped ||= Relation.new(self, arel_table) finder_needs_type_condition? ? @unscoped.where(type_condition) : @unscoped end def arel_table @arel_table ||= Arel::Table.new(table_name, :engine => arel_engine) end end end end module ActiveRecord::NamedScope::ClassMethods def scoped(options = {}, &block) if options.present? relation = scoped.apply_finder_options(options) block_given? ? relation.extending(Module.new(&block)) : relation else current_scoped_methods ? unscoped.merge(current_scoped_methods) : unscoped.clone end end end
  • 4. Scope with Arel class Product < ActiveRecord::Base scope :name_like, lambda { |param| where(self.arel_table[:name].matches("%#{param}%")) } scope :attr_like, lambda { |attr, param| where(self.arel_table[attr].matches("%#{param}%")) } scope :attr_gt, lambda { |attr, param| where(self.arel_table[attr].gt(param)) } end Product.name_like('Ruby') Product.attr_like(:name, 'Ruby') SELECT "products".* FROM "products" WHERE ("products"."name" LIKE '%Ruby%') Product.attr_gt(:price, 100) SELECT "products".* FROM "products" WHERE ("products"."price" > 100)
  • 7. NotMatch ? products = Product.scoped puts products.where(products.table[:name].matches('%Ruby%')).to_sql SELECT "products".* FROM "products" WHERE ("products"."name" LIKE '%Ruby%') products = Product.scoped puts products.where(%Q{"products"."name" NOT LIKE '%Ruby%'}).to_sql puts products.where(%Q{"products"."name" NOT LIKE ?}, '%Ruby%').to_sql SELECT "products".* FROM "products" WHERE ("products"."name" NOT LIKE '%Ruby%') products = Product.scoped products.where(products.table[:name].notmatches('%Ruby%')) products = Product.search products.name_not_like = 'Ruby' products = Product.search('name_not_like' => 'Ruby')
  • 8. NotMatch ! require 'arel' # lib/arel/algebra/predicates.rb module Arel::Predicates class NotMatch < Binary; end end # lib/arel/algebra/attributes/attribute.rb module Arel class Attribute def notmatches(regexp); Predicates::NotMatch.new(self, regexp) end end end # lib/arel/engines/sql/predicates.rb module Arel::Predicates class NotMatch < Binary def predicate_sql; 'NOT LIKE' end end end # lib/arel/engines/memory/predicates.rb module Arel::Predicates class NotMatch < Binary def operator; :"!~" end end end
  • 9. Rails 2.3 => Search Logic Rails 3 => Search Logic
  • 10. Write Your Own Search Method !!!
  • 12. MetaSearch::Searches::Base module MetaSearch::Searches::Base def search(opts = {}) search_options = opts.delete(:search_options) || {} builder = MetaSearch::Builder.new(self, search_options) builder.build(opts) end end ActiveRecord::Base.send :include, MetaSearch::Searches::ActiveRecord Product.search('name_not_like' => 'Ruby')
  • 13. MetaSearch::Builder module MetaSearch class Builder attr_reader :base, :relation, :join_dependency delegate :joins, :includes, :all, :count, :to_sql, :paginate, :find_each, :first, :last, :each, :to => :relation def initialize(base, opts = {}) @base = base @associations = {} @join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@base, [], nil) @relation = @base.scoped end def build(opts) @relation = @base.scoped opts.each_pair {|k, v| self.send("#{k}=", v)} self end name_not_like= end end
  • 14. MetaSearch::Builder module MetaSearch name_not_like= class Builder def method_missing(method_id, *args, &block) if match = matches_attribute_method(method_id) condition, attribute, association = match.captures.reverse build_method(association, attribute, condition) self.send(preferred_method_name(method_id), *args) elsif match = matches_where_method(method_id) condition = match.captures.first build_where_method(condition, Where.new(condition)) self.send(method_id, *args) else super @relation.where(products.table[:name] end .notmatches('%Ruby%') end end end
  • 15. MetaSearch::Where MetaSearch::Where.add(['not_like', 'not_contain', 'notmatches', { :types => [:string, :text, :binary], :condition => :notmatches, Arel:: Attribute#notmatches :formatter => '"%#{param}%"' }]) @@wheres['not_like'] = { :name => 'not_like', :aliases => ['not_contain', 'notmatches'], :types => [:string, :text, :binary], :condition => :notmatches, :formatter => Proc.new {|param| eval '"%#{param}%"'}, :validator => Proc.new {|param| !param.blank?}, :splat_param => false } #=> Where.new(@@wheres['not_like']) Where.new('not_like') == Where.get('not_like') # if new with string
  • 16. More Possibilities ? Article.where(:created_at > 100.days.ago, :title =~ 'Hi%').to_sql SELECT "articles".* FROM "articles" WHERE ("articles"."created_at" > '2010-01-05 20:11:44.997446') AND ("articles"."title" LIKE 'Hi%') http://gist.github.com/265308 http://github.com/ernie/meta_where
  • 17. About Me Tse-Ching Ho http://github.com/tsechingho http://grassbrook.com
  • 18. END