SlideShare ist ein Scribd-Unternehmen logo
1 von 40
Downloaden Sie, um offline zu lesen
Beginner to Builder
                      Week 7




July, 2011
Sunday, July 31, 11
Rails - Week 7
                      • SQL Crash Course
                      • where & find
                      • method_missing
                      • scopes and class methods
                      • Pagination
                      • full text search
                      • Rake vs. Script/Runner
@Schneems
Sunday, July 31, 11
SQL
                      • Structured Query Language
                      • Used to manage data in RDBMS
                        (relational database management system)
                      • Active Record hides our SQL
                        User.where(:username => "foo").to_sql
                        => SELECT "users".*
                           FROM "users" WHERE
                           "users"."username" = 'foo'




@Schneems
Sunday, July 31, 11
Find
                       • find by uniqe id, or ids
                       • find_by_#{:column_name}
                       User.find(1)
                       User.find(1,2,3)
                       User.find_by_username('schneems')




@Schneems
Sunday, July 31, 11
Method Missing
             User.foo_foo
             NoMethodError: undefined method `foo_foo' for #<Class:
             0x105187be8>




@Schneems
Sunday, July 31, 11
Method Missing
             class User
               def self.method_missing(method_name, *args, &block)
                 puts "You just called #{method_name}"
               end
             end

             User.foo_foo
             >> "You just called foo_foo"




@Schneems
Sunday, July 31, 11
Method Missing
             class User < ActiveRecord::Base
              def self.method_missing(method_name, *args, &blk)
                 if method_name.to_s =~ /^foo_foo_find_by_.*/
                   column = method_name.to_s.gsub("foo_foo_find_by_", "")
                   User.where(column.to_sym => args.first)
                 else
                   super
                 end
              end
             end
             User.foo_foo_find_by_username("schneems")



@Schneems
Sunday, July 31, 11
Active Record
                      • Active Record’s Query API
                        find
                        where (:conditions)
                        includes (:include)
                        group
                        order
                        limit
                        offset
                        joins
                        having

             http://m.onkey.org/active-record-query-interface
@Schneems
Sunday, July 31, 11
Order & Offset
                       # Order# defaults to ascending
                         User.order(:created_at).first
                          #<User id: 1, ...
                         User.order('created_at DESC').first
                         #<User id: 55, ...

                       # Offset
                         User.order(:created_at).offset(1).first
                          #<User id: 2, ...
                         User.order(:created_at).offset(2).first
                          #<User id: 3, ...

@Schneems
Sunday, July 31, 11
Limit & Count
                       # Limit
                       User.limit(3).all
                       [ #<User ... >, #<User ... >, #<User ... > ]

                       # Count
                       User.count
                       => 55




@Schneems
Sunday, July 31, 11
Group
                      • Group
                        # Group
                        User.group(:hometown).count(:hometown)
                         #<OrderedHash {
                         "Austin, Texas"=>28,
                         "Alexandria, MN"=>1,
                         "Warsaw, Poland"=>1,
                         # ...
                         }




@Schneems
Sunday, July 31, 11
Joins
          # Joins
          BlogPost.joins(:user).where(:user_id => 2).first
           => #<BlogPost id: 13023, name: The best of times>




@Schneems
Sunday, July 31, 11
Include
                 # Include pre-fetches data
                 User.where(:id => 3).includes(:posts => :comments)


                 user = User.find(3)
                 post = user.posts.all.first
                 post.comments




@Schneems
Sunday, July 31, 11
Having
          # having
          User.group(:hometown).having("COUNT(hometown) > 22").count

          #<OrderedHash
           {"Austin, Texas"=>28,
           "Austin, TX"=>102,
           "San Francisco, CA"=>92,
           "Dallas, TX"=>56}>




@Schneems
Sunday, July 31, 11
Where
                       • can take raw sql statement

                        User.where("username = foo").to_sql
                        => "SELECT "users".* FROM "users"
                        WHERE (username = foo)"




@Schneems
Sunday, July 31, 11
Where
                       • Like

                       # 'Like' does a search using % as wildcard
                       User.where("username like '%foo%'")
                         # will match '...zfoo', 'fooz...', etc.




@Schneems
Sunday, July 31, 11
Where
                       • Null
                        # 'NULL' checks blank entries
                        User.where("username IS NULL")

                        # 'NOT' negates query
                        User.where("username IS NOT NULL")




@Schneems
Sunday, July 31, 11
Where
                       • Equality Operators
                       # '<>' is SQL not equal
                       User.where("username <> 'foo'")

                       # "greater than"
                       User.where("popularity > 5")

                       # "less than"
                       User.where("popularity < 5")


@Schneems
Sunday, July 31, 11
Where
                       • SQL Functions
                  # DATE() is a SQL function
                  User.where("DATE(created_at) > DATE('#{5.days.ago}')")
                    # Other Functions:
                      # AVG, SUM, COUNT, MIN, MAX




@Schneems
Sunday, July 31, 11
Where
                       • (?)   passes data into SQL safely


                  User.where("DATE(created_at) > DATE(?)", 5.days.ago)




@Schneems
Sunday, July 31, 11
SQL Security
                      • SQL injection attacks
                        name = "'' or 1 DROP TABLE USERS"
                        # Bad
                          User.where("name = #{name}")
                        # Good
                          User.where("name = ?", name)
                          User.where(:name => name)




@Schneems
Sunday, July 31, 11
ActiveRecord
                      • Lazy Loading
                         # stores Query, doesn’t hit the DB
                         cars = Car.where(:colour => 'black')
                         # .each Fires "select * from cars where ..."
                         cars.each {|c| puts c.name }

                         # Now We can Chain
                         Item.limit(10).order('created_at DESC')




@Schneems
Sunday, July 31, 11
Scopes
                      • Re-use your queries
               class Product < ActiveRecord::Base
                 scope :discontinued, where(:discontinued => true)
                 scope :cheap, where("price < 5")
               end

               Product.discontinued.first
               Product.discontinued.cheap.first




@Schneems
Sunday, July 31, 11
Scopes
                      • Re-use your queries
        class Product < ActiveRecord::Base
          scope :cheaper_than,
                  lambda { |price| where("price < ?", price) }
        end

        Product.cheaper_than(5).first




@Schneems
Sunday, July 31, 11
Class Methods
                      • Re-use your queries
                      • Better than scopes
        class Product < ActiveRecord::Base
          def self.cheaper_than(price)
            where("price < ?", price)
          end
        end

        Product.cheaper_than(5).first
        Product.cheaper_than(5).order.limit(5).first



@Schneems
Sunday, July 31, 11
Rake
                      # /lib/tasks/users.rake
                      namespace :users do
                        desc "Create dummy users"
                        task :populate => :environment do
                            5.times do
                              User.build(:name => Faker.first_name)
                            end
                        end
                      end

                      # execute with
                      > rake users:populate


@Schneems
Sunday, July 31, 11
Rake
                      • Can be used independently from Rails
                      # /lib/tasks/foo.rake
                      namespace :foo do
                        desc "foo bars"
                        task :bar do
                            # ...
                        end
                      end




@Schneems
Sunday, July 31, 11
Script/Runner


                      # /lib/user_populate.rb
                      5.times do
                        User.build(:name => Faker.first_name)
                      end

                      # execute with
                      > script/runner /lib/user_populate.rb



@Schneems
Sunday, July 31, 11
Rake Wins
                      • Versatile
                      • Useful outside of rails
                      • favored over script/runner




@Schneems
Sunday, July 31, 11
Pagination
                      • Split up large data into chunks
                      • will_paginate gem
    post = BlogPost.paginate :page => params[:page], :per_page => 20

    post.total_count # => 200
    post.count       # => 20




@Schneems
Sunday, July 31, 11
Full Text Search

                      # SQL Like
                      BlogPost.where("title like '%?%", params[:title])
                      # slow
                      # doesn't deal with
                        # punctuation
                        # pluralization
                        # etc.




@Schneems
Sunday, July 31, 11
SOLR
                      • Open Source Search Server
                      • Based on Lucene
                      • Fast
                      • Feature rich
                      • Easily Accessed ruby API wrappers


@Schneems
Sunday, July 31, 11
Sunspot GEM
                      class BlogPost < ActiveRecord::Base
                        searchable do
                          text :title, :body
                          text :comments do
                            comments.map { |comment| comment.body }
                          end
                          time :published_at
                          string :sort_title do
                            title.downcase.gsub(/^(an?|the)/, '')
                          end
                        end
                      end


@Schneems
Sunday, July 31, 11
Sunspot GEM
                      • Paginated
                      BlogPost.search do
                        fulltext 'best pizza'
                        with(:published_at).less_than Time.now
                        order_by :published_at, :desc
                        paginate :page => 2, :per_page => 15
                        facet :category_ids, :author_id
                      end




@Schneems
Sunday, July 31, 11
Sphinx
                      • Open Source
                      • Full text search server




@Schneems
Sunday, July 31, 11
Thinking Sphinx GEM
             class Article < ActiveRecord::Base

               define_index do
                 # fields
                 indexes subject, :sortable => true
                 indexes content
                 indexes author.name, :as => :author, :sortable => true
                 # attributes
                 has author_id, created_at, updated_at
               end
             end


@Schneems
Sunday, July 31, 11
Thinking Sphinx GEM

           Article.search "topical issue"

           Article.search "something",
             :order => :created_at,
             :sort_mode => :desc




@Schneems
Sunday, July 31, 11
Sphinx
                      • Flying Sphinx add-on in heroku




@Schneems
Sunday, July 31, 11
3rd Parties/Black Box
                      • Index Tank
             # Connect to Service
             api = IndexTank::Client.new "<YOUR API URL HERE>"
             index = api.indexes "<YOUR INDEX NAME>"

             # add documents
             docid = "<YOUR DOCUMENT ID>"
             text = "<THE TEXTUAL CONTENT>"
             index.document(docid).add({ :text => text })

             # search documents
             results = index.search "foo"

@Schneems
Sunday, July 31, 11
Questions?
                      http://guides.rubyonrails.org
                       http://stackoverflow.com
                          http://peepcode.com


@Schneems
Sunday, July 31, 11

Weitere ähnliche Inhalte

Mehr von Richard Schneeman

Rails 3 Beginner to Builder 2011 Week 4
Rails 3 Beginner to Builder 2011 Week 4Rails 3 Beginner to Builder 2011 Week 4
Rails 3 Beginner to Builder 2011 Week 4Richard Schneeman
 
Rails 3 Beginner to Builder 2011 Week 3
Rails 3 Beginner to Builder 2011 Week 3Rails 3 Beginner to Builder 2011 Week 3
Rails 3 Beginner to Builder 2011 Week 3Richard Schneeman
 
Rails 3 Beginner to Builder 2011 Week 2
Rails 3 Beginner to Builder 2011 Week 2Rails 3 Beginner to Builder 2011 Week 2
Rails 3 Beginner to Builder 2011 Week 2Richard Schneeman
 
Rails 3 Beginner to Builder 2011 Week 1
Rails 3 Beginner to Builder 2011 Week 1Rails 3 Beginner to Builder 2011 Week 1
Rails 3 Beginner to Builder 2011 Week 1Richard Schneeman
 
Rails3 Summer of Code 2010 - Week 6
Rails3 Summer of Code 2010 - Week 6Rails3 Summer of Code 2010 - Week 6
Rails3 Summer of Code 2010 - Week 6Richard Schneeman
 

Mehr von Richard Schneeman (8)

Rails 3 Beginner to Builder 2011 Week 4
Rails 3 Beginner to Builder 2011 Week 4Rails 3 Beginner to Builder 2011 Week 4
Rails 3 Beginner to Builder 2011 Week 4
 
Rails 3 Beginner to Builder 2011 Week 3
Rails 3 Beginner to Builder 2011 Week 3Rails 3 Beginner to Builder 2011 Week 3
Rails 3 Beginner to Builder 2011 Week 3
 
Rails 3 Beginner to Builder 2011 Week 2
Rails 3 Beginner to Builder 2011 Week 2Rails 3 Beginner to Builder 2011 Week 2
Rails 3 Beginner to Builder 2011 Week 2
 
Rails 3 Beginner to Builder 2011 Week 1
Rails 3 Beginner to Builder 2011 Week 1Rails 3 Beginner to Builder 2011 Week 1
Rails 3 Beginner to Builder 2011 Week 1
 
Potential Friend Finder
Potential Friend FinderPotential Friend Finder
Potential Friend Finder
 
Rails3 Summer of Code 2010 - Week 6
Rails3 Summer of Code 2010 - Week 6Rails3 Summer of Code 2010 - Week 6
Rails3 Summer of Code 2010 - Week 6
 
UT on Rails3 2010- Week 4
UT on Rails3 2010- Week 4 UT on Rails3 2010- Week 4
UT on Rails3 2010- Week 4
 
UT on Rails3 2010- Week 2
UT on Rails3 2010- Week 2UT on Rails3 2010- Week 2
UT on Rails3 2010- Week 2
 

Kürzlich hochgeladen

ESP 4-EDITED.pdfmmcncncncmcmmnmnmncnmncmnnjvnnv
ESP 4-EDITED.pdfmmcncncncmcmmnmnmncnmncmnnjvnnvESP 4-EDITED.pdfmmcncncncmcmmnmnmncnmncmnnjvnnv
ESP 4-EDITED.pdfmmcncncncmcmmnmnmncnmncmnnjvnnvRicaMaeCastro1
 
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...DhatriParmar
 
Expanded definition: technical and operational
Expanded definition: technical and operationalExpanded definition: technical and operational
Expanded definition: technical and operationalssuser3e220a
 
Narcotic and Non Narcotic Analgesic..pdf
Narcotic and Non Narcotic Analgesic..pdfNarcotic and Non Narcotic Analgesic..pdf
Narcotic and Non Narcotic Analgesic..pdfPrerana Jadhav
 
Reading and Writing Skills 11 quarter 4 melc 1
Reading and Writing Skills 11 quarter 4 melc 1Reading and Writing Skills 11 quarter 4 melc 1
Reading and Writing Skills 11 quarter 4 melc 1GloryAnnCastre1
 
4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptxmary850239
 
ClimART Action | eTwinning Project
ClimART Action    |    eTwinning ProjectClimART Action    |    eTwinning Project
ClimART Action | eTwinning Projectjordimapav
 
Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4JOYLYNSAMANIEGO
 
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxDIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxMichelleTuguinay1
 
Scientific Writing :Research Discourse
Scientific  Writing :Research  DiscourseScientific  Writing :Research  Discourse
Scientific Writing :Research DiscourseAnita GoswamiGiri
 
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptxDecoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptxDhatriParmar
 
Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptx
Unraveling Hypertext_ Analyzing  Postmodern Elements in  Literature.pptxUnraveling Hypertext_ Analyzing  Postmodern Elements in  Literature.pptx
Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptxDhatriParmar
 
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdfGrade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdfJemuel Francisco
 
How to Make a Duplicate of Your Odoo 17 Database
How to Make a Duplicate of Your Odoo 17 DatabaseHow to Make a Duplicate of Your Odoo 17 Database
How to Make a Duplicate of Your Odoo 17 DatabaseCeline George
 
Mythology Quiz-4th April 2024, Quiz Club NITW
Mythology Quiz-4th April 2024, Quiz Club NITWMythology Quiz-4th April 2024, Quiz Club NITW
Mythology Quiz-4th April 2024, Quiz Club NITWQuiz Club NITW
 
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Association for Project Management
 
Sulphonamides, mechanisms and their uses
Sulphonamides, mechanisms and their usesSulphonamides, mechanisms and their uses
Sulphonamides, mechanisms and their usesVijayaLaxmi84
 
How to Fix XML SyntaxError in Odoo the 17
How to Fix XML SyntaxError in Odoo the 17How to Fix XML SyntaxError in Odoo the 17
How to Fix XML SyntaxError in Odoo the 17Celine George
 
ICS 2208 Lecture Slide Notes for Topic 6
ICS 2208 Lecture Slide Notes for Topic 6ICS 2208 Lecture Slide Notes for Topic 6
ICS 2208 Lecture Slide Notes for Topic 6Vanessa Camilleri
 

Kürzlich hochgeladen (20)

ESP 4-EDITED.pdfmmcncncncmcmmnmnmncnmncmnnjvnnv
ESP 4-EDITED.pdfmmcncncncmcmmnmnmncnmncmnnjvnnvESP 4-EDITED.pdfmmcncncncmcmmnmnmncnmncmnnjvnnv
ESP 4-EDITED.pdfmmcncncncmcmmnmnmncnmncmnnjvnnv
 
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
 
Expanded definition: technical and operational
Expanded definition: technical and operationalExpanded definition: technical and operational
Expanded definition: technical and operational
 
Narcotic and Non Narcotic Analgesic..pdf
Narcotic and Non Narcotic Analgesic..pdfNarcotic and Non Narcotic Analgesic..pdf
Narcotic and Non Narcotic Analgesic..pdf
 
Reading and Writing Skills 11 quarter 4 melc 1
Reading and Writing Skills 11 quarter 4 melc 1Reading and Writing Skills 11 quarter 4 melc 1
Reading and Writing Skills 11 quarter 4 melc 1
 
4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx
 
ClimART Action | eTwinning Project
ClimART Action    |    eTwinning ProjectClimART Action    |    eTwinning Project
ClimART Action | eTwinning Project
 
Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4
 
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxDIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
 
Scientific Writing :Research Discourse
Scientific  Writing :Research  DiscourseScientific  Writing :Research  Discourse
Scientific Writing :Research Discourse
 
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptxDecoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
 
Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptx
Unraveling Hypertext_ Analyzing  Postmodern Elements in  Literature.pptxUnraveling Hypertext_ Analyzing  Postmodern Elements in  Literature.pptx
Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptx
 
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdfGrade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
 
How to Make a Duplicate of Your Odoo 17 Database
How to Make a Duplicate of Your Odoo 17 DatabaseHow to Make a Duplicate of Your Odoo 17 Database
How to Make a Duplicate of Your Odoo 17 Database
 
Mythology Quiz-4th April 2024, Quiz Club NITW
Mythology Quiz-4th April 2024, Quiz Club NITWMythology Quiz-4th April 2024, Quiz Club NITW
Mythology Quiz-4th April 2024, Quiz Club NITW
 
prashanth updated resume 2024 for Teaching Profession
prashanth updated resume 2024 for Teaching Professionprashanth updated resume 2024 for Teaching Profession
prashanth updated resume 2024 for Teaching Profession
 
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
 
Sulphonamides, mechanisms and their uses
Sulphonamides, mechanisms and their usesSulphonamides, mechanisms and their uses
Sulphonamides, mechanisms and their uses
 
How to Fix XML SyntaxError in Odoo the 17
How to Fix XML SyntaxError in Odoo the 17How to Fix XML SyntaxError in Odoo the 17
How to Fix XML SyntaxError in Odoo the 17
 
ICS 2208 Lecture Slide Notes for Topic 6
ICS 2208 Lecture Slide Notes for Topic 6ICS 2208 Lecture Slide Notes for Topic 6
ICS 2208 Lecture Slide Notes for Topic 6
 

Rails 3 Beginner to Builder 2011 Week 7

  • 1. Beginner to Builder Week 7 July, 2011 Sunday, July 31, 11
  • 2. Rails - Week 7 • SQL Crash Course • where & find • method_missing • scopes and class methods • Pagination • full text search • Rake vs. Script/Runner @Schneems Sunday, July 31, 11
  • 3. SQL • Structured Query Language • Used to manage data in RDBMS (relational database management system) • Active Record hides our SQL User.where(:username => "foo").to_sql => SELECT "users".* FROM "users" WHERE "users"."username" = 'foo' @Schneems Sunday, July 31, 11
  • 4. Find • find by uniqe id, or ids • find_by_#{:column_name} User.find(1) User.find(1,2,3) User.find_by_username('schneems') @Schneems Sunday, July 31, 11
  • 5. Method Missing User.foo_foo NoMethodError: undefined method `foo_foo' for #<Class: 0x105187be8> @Schneems Sunday, July 31, 11
  • 6. Method Missing class User def self.method_missing(method_name, *args, &block) puts "You just called #{method_name}" end end User.foo_foo >> "You just called foo_foo" @Schneems Sunday, July 31, 11
  • 7. Method Missing class User < ActiveRecord::Base def self.method_missing(method_name, *args, &blk) if method_name.to_s =~ /^foo_foo_find_by_.*/ column = method_name.to_s.gsub("foo_foo_find_by_", "") User.where(column.to_sym => args.first) else super end end end User.foo_foo_find_by_username("schneems") @Schneems Sunday, July 31, 11
  • 8. Active Record • Active Record’s Query API find where (:conditions) includes (:include) group order limit offset joins having http://m.onkey.org/active-record-query-interface @Schneems Sunday, July 31, 11
  • 9. Order & Offset # Order# defaults to ascending User.order(:created_at).first #<User id: 1, ... User.order('created_at DESC').first #<User id: 55, ... # Offset User.order(:created_at).offset(1).first #<User id: 2, ... User.order(:created_at).offset(2).first #<User id: 3, ... @Schneems Sunday, July 31, 11
  • 10. Limit & Count # Limit User.limit(3).all [ #<User ... >, #<User ... >, #<User ... > ] # Count User.count => 55 @Schneems Sunday, July 31, 11
  • 11. Group • Group # Group User.group(:hometown).count(:hometown) #<OrderedHash { "Austin, Texas"=>28, "Alexandria, MN"=>1, "Warsaw, Poland"=>1, # ... } @Schneems Sunday, July 31, 11
  • 12. Joins # Joins BlogPost.joins(:user).where(:user_id => 2).first => #<BlogPost id: 13023, name: The best of times> @Schneems Sunday, July 31, 11
  • 13. Include # Include pre-fetches data User.where(:id => 3).includes(:posts => :comments) user = User.find(3) post = user.posts.all.first post.comments @Schneems Sunday, July 31, 11
  • 14. Having # having User.group(:hometown).having("COUNT(hometown) > 22").count #<OrderedHash {"Austin, Texas"=>28, "Austin, TX"=>102, "San Francisco, CA"=>92, "Dallas, TX"=>56}> @Schneems Sunday, July 31, 11
  • 15. Where • can take raw sql statement User.where("username = foo").to_sql => "SELECT "users".* FROM "users" WHERE (username = foo)" @Schneems Sunday, July 31, 11
  • 16. Where • Like # 'Like' does a search using % as wildcard User.where("username like '%foo%'") # will match '...zfoo', 'fooz...', etc. @Schneems Sunday, July 31, 11
  • 17. Where • Null # 'NULL' checks blank entries User.where("username IS NULL") # 'NOT' negates query User.where("username IS NOT NULL") @Schneems Sunday, July 31, 11
  • 18. Where • Equality Operators # '<>' is SQL not equal User.where("username <> 'foo'") # "greater than" User.where("popularity > 5") # "less than" User.where("popularity < 5") @Schneems Sunday, July 31, 11
  • 19. Where • SQL Functions # DATE() is a SQL function User.where("DATE(created_at) > DATE('#{5.days.ago}')") # Other Functions: # AVG, SUM, COUNT, MIN, MAX @Schneems Sunday, July 31, 11
  • 20. Where • (?) passes data into SQL safely User.where("DATE(created_at) > DATE(?)", 5.days.ago) @Schneems Sunday, July 31, 11
  • 21. SQL Security • SQL injection attacks name = "'' or 1 DROP TABLE USERS" # Bad User.where("name = #{name}") # Good User.where("name = ?", name) User.where(:name => name) @Schneems Sunday, July 31, 11
  • 22. ActiveRecord • Lazy Loading # stores Query, doesn’t hit the DB cars = Car.where(:colour => 'black') # .each Fires "select * from cars where ..." cars.each {|c| puts c.name } # Now We can Chain Item.limit(10).order('created_at DESC') @Schneems Sunday, July 31, 11
  • 23. Scopes • Re-use your queries class Product < ActiveRecord::Base scope :discontinued, where(:discontinued => true) scope :cheap, where("price < 5") end Product.discontinued.first Product.discontinued.cheap.first @Schneems Sunday, July 31, 11
  • 24. Scopes • Re-use your queries class Product < ActiveRecord::Base scope :cheaper_than, lambda { |price| where("price < ?", price) } end Product.cheaper_than(5).first @Schneems Sunday, July 31, 11
  • 25. Class Methods • Re-use your queries • Better than scopes class Product < ActiveRecord::Base def self.cheaper_than(price) where("price < ?", price) end end Product.cheaper_than(5).first Product.cheaper_than(5).order.limit(5).first @Schneems Sunday, July 31, 11
  • 26. Rake # /lib/tasks/users.rake namespace :users do desc "Create dummy users" task :populate => :environment do 5.times do User.build(:name => Faker.first_name) end end end # execute with > rake users:populate @Schneems Sunday, July 31, 11
  • 27. Rake • Can be used independently from Rails # /lib/tasks/foo.rake namespace :foo do desc "foo bars" task :bar do # ... end end @Schneems Sunday, July 31, 11
  • 28. Script/Runner # /lib/user_populate.rb 5.times do User.build(:name => Faker.first_name) end # execute with > script/runner /lib/user_populate.rb @Schneems Sunday, July 31, 11
  • 29. Rake Wins • Versatile • Useful outside of rails • favored over script/runner @Schneems Sunday, July 31, 11
  • 30. Pagination • Split up large data into chunks • will_paginate gem post = BlogPost.paginate :page => params[:page], :per_page => 20 post.total_count # => 200 post.count # => 20 @Schneems Sunday, July 31, 11
  • 31. Full Text Search # SQL Like BlogPost.where("title like '%?%", params[:title]) # slow # doesn't deal with # punctuation # pluralization # etc. @Schneems Sunday, July 31, 11
  • 32. SOLR • Open Source Search Server • Based on Lucene • Fast • Feature rich • Easily Accessed ruby API wrappers @Schneems Sunday, July 31, 11
  • 33. Sunspot GEM class BlogPost < ActiveRecord::Base searchable do text :title, :body text :comments do comments.map { |comment| comment.body } end time :published_at string :sort_title do title.downcase.gsub(/^(an?|the)/, '') end end end @Schneems Sunday, July 31, 11
  • 34. Sunspot GEM • Paginated BlogPost.search do fulltext 'best pizza' with(:published_at).less_than Time.now order_by :published_at, :desc paginate :page => 2, :per_page => 15 facet :category_ids, :author_id end @Schneems Sunday, July 31, 11
  • 35. Sphinx • Open Source • Full text search server @Schneems Sunday, July 31, 11
  • 36. Thinking Sphinx GEM class Article < ActiveRecord::Base define_index do # fields indexes subject, :sortable => true indexes content indexes author.name, :as => :author, :sortable => true # attributes has author_id, created_at, updated_at end end @Schneems Sunday, July 31, 11
  • 37. Thinking Sphinx GEM Article.search "topical issue" Article.search "something", :order => :created_at, :sort_mode => :desc @Schneems Sunday, July 31, 11
  • 38. Sphinx • Flying Sphinx add-on in heroku @Schneems Sunday, July 31, 11
  • 39. 3rd Parties/Black Box • Index Tank # Connect to Service api = IndexTank::Client.new "<YOUR API URL HERE>" index = api.indexes "<YOUR INDEX NAME>" # add documents docid = "<YOUR DOCUMENT ID>" text = "<THE TEXTUAL CONTENT>" index.document(docid).add({ :text => text }) # search documents results = index.search "foo" @Schneems Sunday, July 31, 11
  • 40. Questions? http://guides.rubyonrails.org http://stackoverflow.com http://peepcode.com @Schneems Sunday, July 31, 11