• Jump To … +
    assignment.rb associations.rb basics.rb callbacks.rb composite.rb conversions.rb database.rb index.rb modifiers.rb queries.rb spec.rb validations.rb
  • queries.rb

  • ¶

    Example of Queries with [Mongo Model][mongodb_model].

    In this example we’ll see standard MongoDB queries, dynamic finders and scopes.

    require 'mongo/model'
  • ¶

    Connecting to test database and cleaning it before starting.

    Mongo::Model.default_database_name = :default_test
    Mongo::Model.default_database.clear
  • ¶

    Defining Game Unit.

    class Unit
      inherit Mongo::Model
      collection :units
    
      attr_accessor :name, :status, :race
    
      def inspect; name end
    end
  • ¶

    Populating database.

    zeratul  = Unit.create name: 'Zeratul',  race: 'Protoss', status: 'alive'
    tassadar = Unit.create name: 'Tassadar', race: 'Protoss', status: 'dead'
    jim      = Unit.create name: 'Jim',      race: 'Terran',  status: 'alive'
  • ¶

    Standard MongoDB queries (there’s also each method, the same as all).

    p Unit.first(name: 'Zeratul')                        # => Zeratul
    p Unit.all(name: 'Zeratul')                          # => [Zeratul]
    Unit.all name: 'Zeratul' do |unit|
      p unit                                             # => Zeratul
    end
  • ¶

    Simple dynamic finders.

    p Unit.by_name('Zeratul')                            # => Zeratul
    p Unit.first_by_name('Zeratul')                      # => Zeratul
    p Unit.all_by_name('Zeratul')                        # => [Zeratul]
  • ¶

    Bang version, will raise error if nothing found.

    p Unit.first!(name: 'Zeratul')                       # => Zeratul
    p Unit.by_name!('Zeratul')                           # => Zeratul
  • ¶

    Counting and existence checking.

    p Unit.count                                         # => 3
    p Unit.count(race: 'Protoss')                        # => 2
    p Unit.exist?(name: 'Zeratul')                       # => true
    p zeratul.exist?                                     # => true
  • ¶

    You can use Query Builder for complex queries, let’s write sample query with and without it.

    p Unit.all({race: 'Protoss'}, {sort: [[:name, -1]]}) # => [Zeratul, Tassadar]
    p Unit.where(race: 'Protoss').sort([:name, -1]).all  # => [Zeratul, Tassadar]
    p Unit.where(race: 'Protoss').sort(:name).all        # => [Tassadar, Zeratul]
  • ¶

    Sometimes it’s handy to define frequently used queries on the model, such queries called scopes.

    class Unit
  • ¶

    Specifying alive scope to easilly select all alive units.

      scope :alive, status: 'alive'
  • ¶

    If You provide block, it will be dynamically calculated for each query.

    You can also specify default_scope it’s defined like normal scope but unlike it it’s always implicitly applied to all queries.

      scope(:terrans){{race: 'Terran'}}
    end
  • ¶

    Now we can use those scopes in queries. Scopes are chainable, so You can use any standard first, all, find_by, count method as well as another scopes.

    p Unit.alive.count                                   # => 2
    p Unit.alive.first                                   # => Zeratul
    p Unit.alive.by_name('Zeratul')                      # => Zeratul
    p Unit.alive.terrans.first                           # => Jim
    p Unit.alive.where(race: 'Protoss').first            # => Zeratul
  • ¶

    Using pagination.

    per_page = 2
    p Unit.paginate(1, per_page).sort(:name).all         # => [Jim, Tassadar]
    p Unit.paginate(2, per_page).sort(:name).all         # => [Zeratul]
  • ¶

    Mongo Model is tightly integrated with [Driver][mongodb], so You can also use its API for querying.

    db = Mongo::Model.default_database
    p db.units.first(name: 'Jim')                        # => Jim
    p db.units.first(name: 'Jim').class                  # => Unit
  • ¶

    Why there’s no support for

  • ¶

    In this example we covered how to use standard MongoDB queries, dynamic finders, scopes and query builder.