Skip to content

Integrating the mindbody_api into a RefineryCMS engine

Marshal Linfoot edited this page Feb 20, 2014 · 2 revisions

I was developing a website using RefineryCMS and needed to include classroom schedule information from Mindbodyonline (MBO). I created a Refinery engine for this purpose and then set about investigating ways to retrieve the information from MBO’s published API. Fortunately, I stumbled upon Stafford Brunk’s mindbody_api gem and the task became much simpler.

Here’s what I did.

Create the Refinery engine.

I called it “schedule”. From the root of your Refinery tree, run:

rails generate refinery:engine schedule title:string

This creates the scaffolding for the engine. Note: Refinery engines require a model but it’s not necessary to use the resulting database if data persistence is not needed. More information can be found in the Guides section of the RefineryCMS website. We’ll modify the model code shortly.

Update the Gemfile and run Bundler to install.

gem 'mindbody-api', :git => 'git://github.com/wingrunr21/mindbody-api.git'
bundle install

Add an initializer to Refinery’s initializers.

I called it /config/initializers/refinery/mind_body_init.rb:

MindBody.configure do |config|
  config.site_ids    = <SITE-ID>
  config.source_key  = '<SOURCE-KEY>'
  config.source_name = '<SOURCENAME>'
  config.log_level   = :info 
end

Note: Replace “<…>” with your specifics. See the Getting Started with the MindBody API gem for more information about Mindbodyonline credentials if you don’t already have them.

Replace the model scaffolding.

Replace vendor/extensions/schedules/models/refinery/schedules/schedule.rb, with code to retrieve data from the MBO API:

module Refinery
  module Schedules
    class Schedule

    def self.fetch_mindbody_schedule(*opts)
        options = opts.extract_options!
        start_date = options[:start_date] || Date.today.beginning_of_week
        end_date = options[:end_date] || Date.today.end_of_week

        message = {
          'StartDateTime' => start_date,
          'EndDateTime' => end_date,
          'HideCanceledClasses' => false # highlight them in the view
        }
        message['ClientID'] = options[:user_id] unless options[:user_id].nil?
        res = MindBody::Services::ClassService.get_classes(message)
        classes =  res.result[:classes]
        classes.sort!{|a,b| a.start_date_time <=> b.start_date_time}
        return classes
      end
    end
  end
end

Modify the controller.

Change the vendor/extensions/schedules/app/controllers/refinery/schedules/schedules_controller.rb file to get the class schedule:

module Refinery
  module Schedules
    class SchedulesController < ::ApplicationController

      before_filter :find_page

      def index 
        #Get 7 days of classes starting today # adjust start_date and end_date as needed
        @schedule = Refinery::Schedules::Schedule.fetch_mindbody_schedule(:start_date => Date.today, :end_date => Date.today + 6)
      end

      protected

      def find_page
        @page = ::Refinery::Page.where(:link_url => "/schedules").first
      end

    end
  end
end

Almost done…

Just the view left. Modify vendor/extensions/schedules/views/refinery/schedules/schedules/index.html.erb to something like:

<% content_for :body do %>
  <section class="class_schedule">
  <header>
    <h1>Class Schedule</h1>
  </header>
  <!-- if you want additional text on the page -->
  <p><%=raw @page.content_for(:body) %></p>
<!-- now comes the schedule data from MBO -->
<table>
<!-- new header when day of the week changes -->
<% day = " " %>
<% @schedule.each do |one_class| %>
  <% this_day = one_class[:start_date_time].strftime("%A, %B %e") %>
  <% if this_day != day %>
    <% day = this_day %>
    <thead><tr><th colspan='2'><%= day %></th></tr></thead>
  <% end %>
<!-- one class per row -->
  <tr>
    <td>
      <%=raw class_time(one_class[:start_date_time], one_class[:end_date_time], one_class[:is_canceled]) %>
    </td>
    <td>
      <%=raw class_instructor(one_class[:staff][:name], one_class[:is_canceled], one_class[:substitute]) %>
    </td>
    <td>
      <%=raw class_name(one_class[:class_description][:name], one_class[:is_canceled]) %>
    </td>
  </tr>
<% end %>
</table>  
</section>
<% end %>

<%= render '/refinery/content_page' %>

Note: class_time, class_instructor, and class_name are helper methods for tidying up the start/end times, striking through cancelled classes, linking to instructor profiles, etc. Helper methods for Refinery engines need to go into the top-level helpers. Mine went into /app/helpers/refinery/schedules/schedule_helper.rb.

That’s it! I hope someone else finds this helpful. I’m new to Rails and RefineryCMS, so please correct any errors you spot and/or make suggestions for better ways to implement.

A big Thank You to Stafford Brunk for the gem and to qmclaugh for the “Getting Started with the MindBody API gem” article.