SlideShare una empresa de Scribd logo
1 de 18
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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
 

Similar 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
 

Similar 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...)
 

Más 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
 

Más 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

Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 

Último (20)

Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 

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