MongoMapper Example

Yvette Cook edited this page Aug 18, 2016 · 13 revisions

Setting up Picky to use MongoDB with MongoMapper

For MongoDB awesomeness, just add the following files to your picky-server application.

Add the mongomapper gem to your Gemfile

Gemfile

    gem 'mongo_mapper'

Run

bundle install

lib/initializers/mongo.rb

    settings = YAML.load(File.read(File.expand_path('../../config/mongo.yml', File.dirname(__FILE__))))["#{PICKY_ENVIRONMENT}"]
    MongoMapper.connection = Mongo::Connection.new(settings['host'], settings['port'])
    MongoMapper.database = settings['database']

config/mongo.yml

    development:
      adapter: mongodb
      database: fate_of_humankind_development
      host: localhost

    production:
      adapter: mongodb
      database: fate_of_humankind_production
      host: localhost

    test:
      adapter: mongodb
      database: fate_of_humankind_test
      host: localhost

How to use embedded documents with picky server

There might be several ways to approach this problem, a really cool way is to use a Delegator class. Let us assume, we have a model called person. This person has one cat. The cat has a few wishes.

lib/models/person.rb

    class Person
      include MongoMapper::Document

      key :first_name,     String
      key :last_name,      String
      key :favourite_beer, String
      key :job,            String

      has_one :cat
    end

lib/models/cat.rb

    class Cat
      include MongoMapper::EmbeddedDocument

      key :name,      String

      belongs_to :person
      has_many :wishes      
    end

lib/models/wish.rb

    class Wish
      include MongoMapper::EmbeddedDocument

      key :type,     String
      key :cost,     Integer

      belongs_to :cat
    end

Ok, so how do we help our poor person to keep track of the wishes of their cat with picky power? As mentioned above with a Delegator class

lib/cat_delegator.rb

    module CatDelegator
      def cat
        cat.name
      end

      def wish_type
        cat.wishes.map(&:type).join(" ") unless cat.wishes.blank?
      end

      def wish_cost
        cat.wishes.map(&:cost).join(" ") unless cat.wishes.blank?
      end
    end

Change your person class to look like this:

lib/models/person.rb

    require "cat_delegator"

    class Person
        include MongoMapper::Document
        include CatDelegator

        ...
    end

Last step is to change the application.rb accordingly:

app/application.rb

    require "lib/models/person"
    require "lib/models/cat"
    require "lib/models/wish"

    class PickySearch < Application   
      ...

      men = Index::Memory.new(:person) do
        source Person.all

        key_format :to_s
        category :first_name,       partial: Partial::Substring.new(from: 1)
        category :last_name,        partial: Partial::Substring.new(from: 1)
        category :favourite_beer,   partial: Partial::Substring.new(from: 3)
        category :job,              partial: Partial::Substring.new(from: 3)

        category :cat,              partial: Partial::Substring.new(from: 1)
        category :wish_type,        partial: Partial::Substring.new(from: 3)
        category :wish_cost,        partial: Partial::Substring.new(from: 3)
      end

      complete_search = Search.new person
      route %r{^/person$} => complete_search
    end

Well, that's all folks.