extensions

Fabrication

Paul Elliott's Fabrication gem is a slick object generation library. It support's Mongoid out of the box and provides a nice syntax for creating objects with ease for testing.

Fabricator(:person) do
  title "Grand Poobah"
  addresses(count: 2) do |address, i|
    Fabricate(:address, streeet: "#{i} Bond St.")
  end
end

Voting

Alex Nguyen's voteable_mongo gem add up / down voteability to Mongoid and MongoMapper. It takes advantage of document-oriented & in-place update to ensure data integrity and use only ONE database request to validate, update & get updated vote data.

class Post
  include Mongoid::Document
  include Mongo::Voteable
  voteable self, :up => 1, :down => -2
end

class User
  include Mongoid::Document
  include Mongo::Voter
end

user.vote(post, :down)
# => <Post .. votes: {"up"=>[], "down"=>[..], "count"=>1, "point"=>-2, ..}>
user.voted?(post)
# => true
user.vote_value(post)
# => :down

Will Paginate Mongoid

Lucas Souza's will_paginate_mongoid gem becomes possible use skip and limit methods from Mongoid with will_paginate

Why I should use will_paginate_mongoid?

Will Paginate does not support Mongoid pagination (skip and limit methods) and this issue can cause performance problems. For example: If you use just will_paginate to paginate a model called User, in your controller you will call this:

User.paginate :page => params[:page], :per_page => 10

The code above appears that will bring just 10 users from Mongodb, but will bring all users from Mongodb.

With will_paginate_mongoid this issue is solved because it creates the same pagination method but using skip and limit methods bringing just the needed objects from Mongodb.

Geo Spacial Search

Ryan Ong's mongoid_spacial gem extends complex criteria options and simplifies geo spacial row creation, search and return. It adds a few helpers and it also adds a wrapper around the geoNear function that has support for pagination and automatic unit conversion.

class River
  include Mongoid::Document
  include Mongoid::Spacial::Document

  field :name, type: String
  field :source, type: Array, spacial: true

  # set return_array to true if you do not want a hash returned all the time
  field :mouth, type: Array, spacial: {lat: :latitude, lng: :longitude, return_array: true }

  spacial_index :source
end

hudson = River.create(
  name: 'Hudson',
  # order agnostic
  source: {:lat => 44.106667, :lng => -73.935833},
  mouth: {:latitude => 40.703056, :longitude => -74.026667}
)

hudson.distance_from(:mouth, [-74,40], :mi)

# Automatic unit conversion for spherical query, support for $near and $within
River.where(:source.near(:sphere) => {:point => [-73.98, 40.77], :max => 5, :unit => :km})

# Adds chainable paginatable geo_near finder.
# Returns paginated sorted by distance list of rivers where
# name = Hudson and skips the first row with pagination
River.skip(1).where(name: 'Hudson').geo_near([-73.99756,40.73083], page: 1)