contributing

Mongoid is open source and embraces the social coding aspect of github. Here are some guidelines on contributing to the project and ensuring fast acceptance of your contributions.

core contributions

Fork the repo on github and issue a pull request with your changes. No other means of supplying code to the team will be accepted.

Provide specs with your pull request if the existing specs do not cover the change. Pull requests that provide new functionality without specs will not be pulled in under any circumstance.

running the specs

Getting set up should require minimal effort:

  • Install MongoDB.
  • Fork and clone the repository.
  • Run gem install bundler to get the latest for the gemset.
  • Run bundle install for dependencies.
  • Run rake to execute all specs.

Mongoid provides a watchr script as well for easy automated testing. To run it from the project root:

$ bundle exec watchr .watchr

spec guidelines

The following code demostrates the desired way to write a spec in Mongoid. For organization, specs are divided into two directories: spec/functional and spec/unit. Functional specs are those that test the full stack and hit the database, unit specs test a single class in isolation. It's not required to have both, but at least one or the other. Also adhere to these rules:

  • Use describe blocks for method names.
  • Use context blocks for conditions.
  • Prefer let over the use of instance variables.
  • 1 assertion per example block.
  • When describing methods, prefix with # for instance methods, . for class methods.

require "spec_helper"

describe Mongoid::Relations::Embedded::Many do

  before do
    Person.delete_all
  end

  describe "#=" do

    context "when the parent is a new record" do

      let(:person) do
        Person.new
      end

      let(:address) do
        Address.new
      end

      before do
        person.addresses = [ address ]
      end

      it "sets the target of the relation" do
        person.addresses.should == [ address ]
      end
    end
  end

  describe ".macro" do

    it "returns :embeds_many" do
      described_class.macro.should == :embeds_many
    end
  end
end

coding guidelines

Mongoid has the design philosophy of having many fine grained, single purpose objects in its domain. It makes the design more flexible and much easier to test. If you find yourself refactoring at all, extract class is always a good refactoring technique to have in mind.

Here are some other simple rules that will help expidite your patch acceptance.

  • Keep method line counts small and easy to read.
  • Do not fear the use of Ruby's tap.
  • Copy and pasted code from another library will never be accepted.
  • Provide API documentation in the form of YARD.

# encoding: utf-8
module Mongoid # :nodoc:
  module Relations #:nodoc:

    # This module contains the core macros for defining relations between
    # documents. They can be either embedded or referenced (relational).
    module Macros
      extend ActiveSupport::Concern

      module ClassMethods #:nodoc:

      # Adds the relation back to the parent document. This macro is
      # necessary to set the references from the child back to the parent
      # document. If a child does not define this relation calling
      # persistence methods on the child object will cause a save to fail.
      #
      # @example Define the relation.
      #
      #   class Person
      #     include Mongoid::Document
      #     embeds_many :addresses
      #   end
      #
      #   class Address
      #     include Mongoid::Document
      #     embedded_in :person
      #   end
      #
      # @param [ Symbol ] name The name of the relation.
      # @param [ Hash ] options The relation options.
      # @param [ Proc ] block Optional block for defining extensions.
      def embedded_in(name, options = {}, &block)
        characterize(name, Embedded::In, options, &block).tap do |meta|
          self.embedded = true
          relate(name, meta)
        end
      end
    end
  end
end

website contributions

The Mongoid website is open source as well, and hosted on github. It uses middleman as a static content generator, and additions to the documentation are always welcome. The same rules apply here:

Fork the repo on github and issue a pull request with your changes. No other means of supplying code to the team will be accepted.

Getting set up here is easy as well:

  • Fork and clone the repository.
  • Run gem install bundler to get the latest for the gemset.
  • Run bundle install for dependencies.
  • Run bundle exec mm-server to run the site with sinatra.

Pull requests will be merged in and regenerated to the mongoid.github.com repo where you're contributions can be seen in all their glory.