Contributor's Guide

Marc Heiligers edited this page Feb 5, 2014 · 3 revisions
Clone this wiki locally

MadCart Contributor's Guide

Contributing

At Mad Mimi we are actively looking for new MadCart integrations and so we will pay a bounty of $500 for any new CRM/Shopping Cart integrations that follow the guidelines and are well tested. Please make sure you have cleared the integration with us before embarking on the project to build the integration. You can discuss which integration you would like to build with us over here or if you prefer, shoot us an email to developers@madmimi.com

  1. If you're going to add an integration, let us know which over here
  2. Fork it
  3. Create your feature branch (git checkout -b my-new-feature)
  4. Commit your changes (git commit -am 'Add some feature')
  5. Push to the branch (git push origin my-new-feature)
  6. Create new Pull Request

Some ground rules

  • You must let us know which integration you would like to build over here
  • We must confirm that you are working on the integration
  • We will only accept one person or team working on a particular integration (this is not a competition)
  • You have 2 weeks within which to deliver the integration after which we may pass it on to another interested person or team
  • We will pay the $500 bounty via PayPal
  • We are the final arbiters of whether an integration is complete enough, well written enough, documented enough and well tested enough to be accepted

The CRM/Store Class

The CRM/store class can be placed in the MadCart::Store module. Integration hinges around the MadCart::Store::Base mixin. It provides a simple DSL for integrating stores.

module MadCart
  module Store
    class MyStore
      include MadCart::Store::Base

      [...]
    end
  end
end

The mixin adds four class methods: create_connection_with, fetch, format, and after_initialize.

create_connection_with

This tells MadCart how to create the connection object that will interface with your CRM or store. This can be an HTTP object (MadCart's existing stores use Faraday for HTTP connections), a store-specific gem, or any object that provides an interface to the external API.

create_connection_with allows the optional specification of required initializer arguments, which will be passed as a hash. These arguments can come from the MadCart.configure #add_store config, or the store initializer (or a combination of both). An ArgumentError will be raised if any of them are missing.

create_connection_with accepts a method reference:

module MadCart
  module Store
    class MyStore
      include MadCart::Store::Base

      create_connection_with :connection_method, requires: [:username, :password]

      def connection_method(args)
        # return the connection object here.
        # args[:username] and args[:password] are available
      end
    end
  end
end

...or a Proc:

module MadCart
  module Store
    class MyStore
      include MadCart::Store::Base

      create_connection_with Proc.new { 
                                        # return the connection object here. 
                                        # args[:api_key] is available.
                                       },
                                       requires: [:api_key]

    end
  end
end

The connection object will be available as #connection on the store instance.

fetch

fetch sets up a named resource on the store object. It can be called as many times as you'd like.

It also accepts a method reference or a Proc.

module MadCart
  module Store
    class MyStore
      include MadCart::Store::Base
      fetch :products, :with => :fetch_method

      def fetch_method
        connection.get('/products') 
      end

    end
  end
end

format (optional)

format specifies how to format the retrieved data for MadCart::Model initialization. It allows you to separate the MadCart-specific formatting from the CRM/store integration defined by fetch. format acts like the map method in Ruby. Just like map, it takes one argument - a single instance of the list returned by the fetch method - and maps the fetch result to the formatted result. This method can return any MadCart::Model instance, or a hash. If a hash is returned the MadCart::Model will be instantiated automatically using the hash as arguments.

module MadCart
  module Store
    class MyStore
      include MadCart::Store::Base
      fetch :products, :with => :fetch_method

      format :products, :with => Proc.new{|product| {:name => product[:title], :description => product[:description] } }

    end
  end
end

after_initialize (optional)

after_initialize allows a hook point after initialise. It also accepts a method or Proc, and will receive whichever arguments are passed to the class initialiser.

module MadCart
  module Store
    class MyStore
      include MadCart::Store::Base
      fetch :products, :with => :fetch_method

      after_initialize :log_connection

      def log_connection(init_args)
        puts "connection made to #{init_args[:store_name]}"
      end

    end
  end
end

o = MadCart::Store::MyStore.new(:store_name => "Super Great Store")
# connection made to Super Great Store

TODO:

  • A Rake task to list all currently supported model property names (to facilitate standardization).
  • The ability to opt out of a model's default properties.
  • Shopping cart integration.
  • More stores!