Blog Archives

Project Profile: The Tasting Team and BARPOP

Posted in Featured, Project Profile, Rebranding, Ruby on Rails

The Tasting Team are a Perth based company that organise and run tasting sessions in bottle shops, pubs and bars. Originally a Perth based service they have experienced massive growth and have proven to be a great success Australia wide. During this period of growth they came to us with an urgent request; they needed a new booking system and revamped website and they needed it quick.

The new booking system needed to handle a rapidly growing number of tasting sessions and staff, as well as have the SMS capabilities that form the backbone of their business coordination. Due to the need for a quick development we leveraged what we know best and built the booking system as a well tested Ruby and Rails app. With some intense tweaking and refinement the end result has become an efficient and easy to use booking system, with a responsive mobile interface for staff, product representatives and clients to use on the go.

One of the less visible benefits from the work has been improved communication. We have implemented automated reporting and communication which has taken some of the pressure off of management staff giving them more time to coordinate. We have also received positive feedback from the product representatives out in the field who are now getting weekly updates and automated feedback about their many upcoming events.

The revamped website needed to work as a portal for both new and existing clients and staff, as well as show off the services The Tasting Team has to offer. We decided on an continuous scrolling design that’s not only slick to look at but quick to design and build.

tastingteamphone

An important component of the design brief was to show off the small brands and microbreweries The Tasting Team represented.

The Tasting Team Brands

The Tasting Team Brands

It was equally important for the design to reflect the casual, relaxed and professional sessions they run. We decided to integrate photos from The Tasting Team’s own instagram stream into the design.

Near the end of this project the guys at The Tasting Team approached us to design a simple but striking website to show off their latest venture BARPOP, a pop up bar that transforms any space, rooftop, office or event into a licensed bar with a casual atmosphere.

BarPop Website

BarPop Website

The design drew inspiration from the the existing logo and bold colour scheme. It needed to reflect the laid back but professional bar experience BARPOP creates and showcase the brands they have on offer. We wanted to create consistency across all of The Tasting Team websites so used the continuous scrolling idea again interspersed with candid photographs of previous BARPOP events that are pulled straight from the BarPop Instagram feed. The end result is a warm, inviting website that enhances the brand. The clients were thrilled and so were we.

Reflecting on RubyMotion Experiences – Part 1

Posted in Featured, Inside TFG, Ruby on Rails, RubyMotion

At The Frontier Group we develop native and hybrid mobile apps for both iOS and Android. I’ve been developing in RubyMotion since late 2012 and as we begin our 6th RubyMotion app at The Frontier Group, collectively having put over 3000 hours into this technology I have a couple of quick tips for fresh Rails to RubyMotion converts:

rubymotion

1: Forget everything you know about Rails

It’s tempting when you start RubyMotion to assume that since you’re vaguely familiar with MVC that you’ll be able to slap together a fairly decent iOS app. However, MVC in Cocoa Touch and MVC in Rails are completely different.

My advice: Don’t even think of controllers in Rails when you’re trying to build a controller in Cocoa Touch.

Before you start, have a couple of reads through the excellent Apple documentation on view controllers.

Another practice that tripped me up was how used I was to not having any state in Rails applications. That is, in Rails, if you get user input and you don’t need to discard it, you’re probably going to dump it in your database if you want to be able to use it somewhere.

In Cocoa Touch, and really in any client applications, state behaves a lot differently. Data plays a much different role. Persisting data is a fairly expensive operation and is usually not necessary. Many of the apps you make will just be frontends consuming an API. Keep in mind that the way you interact with data will be very different: Objects will persist beyond a single page load.rails

Another interesting idea you might want to familiarize yourselves with is that views in Cocoa Touch are first class citizens. In Rails, we tend to use the terms views and templates interchangeably. I think many Rails developers would benefit from looking up the term ViewModel. Anyway, that’s another post entirely.

In Rails, views are largely just templates. You jam data in, and out pops some markup for the user to see.

In Cocoa Touch, views are entire classes of their own, complete with state and behaviour. You can do a lot in the way of organising your system by leveraging these powerful objects. Have a read about Cocoa Touch views in Apple’s online documentation.

2: Adopt the Cocoa Touch culture

Remember when Rails started getting traction and all the PHP developers jumped over and started writing PHP in Ruby on Rails? Raw SQL everywhere, 12000 LoC controllers, and testless classes in every corner of the app.

I get the feeling that the Rails to RubyMotion expats are doing the same. One of the most egregious practices that RubyMotioners seem to be embracing is the use of snake_case. Have a look at the ProMotion library as an example. ProMotion has created a bunch of mappings between the Cocoa Touch camelCased methods and provided a snake_cased equivalent.

So instead of using Cocoa Touch’s viewDidLoad method, ProMotion wants you to use on_load.

I have a bunch of problems with this practice. Firstly: Cocoa Touch already provides a `viewDidLoad` method, complete with comprehensive documentation, and tonnes of examples available online. Good luck to a newbie developer who isn’t aware that `on_load` and `viewDidLoad` are equivalent, trying to find out how to use the method effectively.

Secondly: What does having snake_case get us here? It feels a lot like a bunch of Rails programmers refusing to let go. Ruby on its own, and in the context of Rails, uses snake_case as a standard. A standard, not a requirement. However: we aren’t working in straight Ruby, nor are we working in Rails. We’re using RubyMotion, a Ruby toolchain that communicates directly with Cocoa Touch. Cocoa Touch, of course, being a massive framework written in Obj-C that uses camelCase as a standard.

If you move to another country, you learn their language. I think it’s the same idea here. We are trying to work in the Cocoa Touch land, so we should use camelCase. Where snake_case has the only benefit of looking familiar to Rubyists and Rails devs, it has the drawbacks of forcing you to either:

Write an interface to all of Cocoa Touch that changes every single method from camelCase to having a snake_case equivalent, or
Mix and match your snake_case methods with Cocoa Touch’s camelCase method.

Both of these options are bad.

The first option requires a tonne of superfluous work that could be avoided by just adopting camelCase (just for the record – Matz won’t track you down and break your legs if you do that!).

The second option requires you to have an inconsistent interface – which is undesirable, to say the least. Consistency is key for writing easily understandable and maintainable code.

My final point on this topic: If you’re ever trying to solve a problem in your app, remember that firstly you should be looking for solutions in the context of Cocoa Touch, not RubyMotion. There are very few bugs you’ll encounter that are actually caused by RubyMotion. For the most part, it’s just going to be you using Cocoa Touch in ways it isn’t meant to be used.

3: Learn some Obj-C

Obj-C looks like the syntax was derived at random from a bag of broken glass, barbed wire, and salt. However, it’s the backbone of the framework you’re working in, so it behooves you to spend some time learning it. There are a lot of benefits, and the main one is this:

XCode

You’re frequently going to have to convert Obj-C code to RubyMotion. You’ll need to understand how Obj-C works to do this.

Here’s another – if you’re going to use CocoaPods, you’re going to need to be able to debug them. This brings me to my next point.

4: Use CocoaPods

CocoaPods is a bundler inspired dependency manager. As a Rails developer the idea should be pretty familiar to you.

CocoaPods has been around since 2011, so suffice it to say anything you need to do can probably be done by one CocoaPod or another.

Think outside the RubyMotion box. You can and should leverage CocoaPods in order to speed up the development of your apps.

Cocoa controls is a good resource for staying up to date on the latest CocoaPods.

RubyMotion’s motion-cocoapods makes using CocoaPods super simple, give it a try!

Here’s a couple of CocoaPods that will give you an idea of how useful they can be:

  • If you’ve ever tried loading remote images in to UITableViewCells, you’ve probably noticed that it can be a real pain. SDWebImage provides an easy to use interface for solving this issue, by providing both downloading and caching of remote images.
  • In client apps, you’re going to have to find a way to communicate to the user that the app is waiting for a remote service. You could spend 15 minutes writing your own loader class, or you could use the wonderful MBProgressHUD.

You can search for CocoaPods on the CocoaPods homepage.

This is the first part of a series on our experiences at The Frontier Group.

before_action an anti-pattern?

Posted in Code, Featured, Ruby on Rails

Some background

@d = 25

Here at The Frontier Group we have recently started using Rails 4 for our new projects and even migrating a couple of older ones. It’s taken a little while, but we feel that it’s been out in the wild long enough, giving a chance for most of the major bugs to be weeded out. Amongst many of the new features, one is before_action which is a new name for the trusty old before_filter. It’s my opinion that renaming it was a bad move as it encourages misuse. This is a controversial opinion to hold; even within TFG. But in any case, before jumping to the comments to tell me of my errors, let me make my case.

In the beginning, I believe the intentions of the humble before_filter were pure. They were to provide a method to prevent an action from ever running; effectively filtering the action before it runs, hence the name. This seems to be supported by the ActionPack README from 1.2 up until 3.2. As of 4.0 that README becomes quite sparse. If you don’t feel like looking at seven year old documentation, examples of before_filter are used to invoke methods such as :authenticate, :cache, and :audit. Suspiciously missing are examples using before_filter to load instance variables such as before_filter :find_post. In fact, the examples of how ivars are used to link the controller and template look like this:

def show
  @customer = find_customer
end

def update
  @customer = find_customer
  # more stuff down here
end

I suspect that the abuse of before_filter started, or at least became popular when gems like CanCan started to emerge. For those unfamiliar, CanCan provides a method called load_and_authorize_resouce which does pretty much exactly what it says it does. It loads a resource then authorizes an action upon it. Should the current user be un-authorized to perform the action, it doesn’t get executed. Presumably much the same way as before_filter :authenticate from the ActionPack Readme would do. With one caveat, it also loads a resource into an ivar of the same name. This leads to our new controller looking like this:

load_and_authorize_resource :post

def show
  # @post has been set CanCan
end

def update
  # @post has been set CanCan
  # more stuff down here
end

Coupled with the ease provided by CanCan, and one of the most overused acronyms and default go to response that I’ve seen since working with Rails (that’s DRY btw), this idea exploded. Note that I actually have NO data to back this up; it’s just speculation. Regardless of the actual cause, I now see code like the following:

before_filter :find_posts, except: [:show]
before_filter :find_post, only: [:show]
before_filter :find_commenters, only: [:show]

def index()
end

def my_posts()
  @posts = @posts.created_by(current_user)
end

def show()
end

private

def find_post()
  @posts = Post.find(params[:id])
end

def find_posts()
  @posts = Post.all
end

def find_commenters()
  @post.comments.map(&:creator).uniq
end

This is an anti-pattern and absolutely terrible code, all for the sake of DRY. At least in Rails 1 through 3, there was an indication that you were doing it wrong via the method name due to the lack of any form of filtering. Now with before_action it seems to be encouraged.

The reasons

First off, the reasons arguing that it’s good.

For: It’s DRY

This code is very DRY. There is no repetition to be found here. In fact there is nothing in the methods at all, so there is nothing to repeat. Of course the benefits of not duplicating code are well documented and proven. If there is a bug in that code, there is only one place to fix it; saving time, effort, and you’re note going to forget to fix it in *that* other place.

For: It’s the Rails way

Using before_filters in this way seems to have become the rails way, with rename to before_action adding legitimacy. There is something to be said to doing what other people expect. It means that they can come into your work and know exactly whats going on. And indeed that’s true, deviating from convention can lead to some level of confusion. So if you intend on doing something other than the convention, you should have a sound reason.

On that note, why do I dislike the current usage?

Against: It’s not anymore DRY

Just above I mention that using DRY as a reason to use before_actions. And in fact DRY is a go to reason for many things, before_actions not withstanding. The only issue is that you are still repeating yourself with before_actions. Note those pesky only: keys, they violate DRY as exactly the same amount as calling the method in your action. You just swap what you’re repeating. In one case you repeat the action name, in the other it’s the name of the filter (using the term lightly) method.

I would propose not setting the variable inside that method, and in which case you do end up repeating the variable name. But you don’t have to, in order to stop using before_action. Compare the two code samples below:

before_action :find_post, only: :show

def show
end

is equivalent to:

def show
  find_post
end

In fact, it’s even shorter doing it in the action!

Against: Except is terrible

Admittedly you can get away from repeating the action names by using except: over only:. Black lists always leave a nasty taste in my mouth when it comes to coding. They presume you know any future uses, or can ensure that any future maintainer is aware of the list and it also needs updating. You can’t be sure that your before action isn’t going to blow over the results of another before action (see my point on side effects below), or admittedly a less sinister action of loading records that aren’t required.

Note that omitting both only: and except: is the same as adding except: []

Against: They abstract the flow of the action from the developer

It’s quite obvious they occur before the action does; after all it says it in the method name before_action. What isn’t obvious is how they play with each other. Looking at the example above, note where the order of execution is defined and where it actually matters. Also all actions need to have consistent input parameters, see how show doesn’t have any control over which post to actually show.

Against: They elevate the live time of the variables

This ties pretty closely to my previous reason. Code Complete discusses the concept of live time (hopefully that link works for you all). The basic concept is that, the further variables are defined from their usage, the more difficult the code becomes to maintain.

@a = 2
@b = 3
@c = @a + @b

The value of @c should be obvious to all. However what about @c + @d? How easy was it for you to say 30?

Against: They have to cause side effects

I dislike side effect causing functions. There I said it. I’m a side-effectist. Every chance to I get to eliminate one is a little personal victory. Eric Evans has a pretty nice explanation of their pitfalls in his book Domain Driven Design. I’m not going to preach benefits the benefits of side effect free functions, except to say that any method that changes state introduces a chance that, that method will be used without knowledge of that side effect. On their own, there is nothing wrong with side effect causing methods, we can’t do our job without them. However they do compound complexity, as you need to understand the side effects of every method in the call chain. You should consider if you really do need to modify state in a method before doing so. To make matters worse, these methods often have un-assuming names, like find_post, which provides no indication state will be changed.

Against: Actions must rely on the side effects of other methods

By using a before_action to configure state, you remove that responsibility from the action. However the sole purpose for an action to exist is to configure, and maybe work with, that state. In effect you are robbing the action of its only job. The first place you look for action code is the action itself. It is not acceptable that a developer should be expected to have to search the entire controller, and any it inherits from, to discover how/why an action is/isn’t working.

In summary

I would love to see the use of before filters/actions returned to their (in my opinion originally intended) use of preventing actions from executing. And use of them solely to load data banished to the annals of history. Code such as the following, despite being slightly longer, reads far better, and is easier to comprehend and maintain:

def show
  @post = find_post
  authorize!(:read, @post)
  @commenters = find_commenters_on_post(@post)
end

def update
  @post = find_post
  authorize!(:update, @post)

  # update it!
end

PetRescue – the design, the rebuild and the launch

Posted in Agile Development, Inside TFG, Ruby on Rails

Earlier this year we were introduced to PetRescue, who were looking for a development company to rebuild their web application that had initially been built and tweaked over the past 8 years by one of the founders.

PetRescue is a not-for-profit organisation that finds new permanent homes for rescue pets. They are Australia’s largest on-line directory of homeless animals, and to date we have helped find new, loving families for over 140,000 pets. PetRescue started in 2004 as a small not-for-profit team dedicated to finding new homes for lost and abandoned pets, with the belief they had something to contribute to improving outcomes for rescue animals across the country.

PetRescue is a web application for both the general public looking to adopt a pet, and rescue groups around the country to list their pets for adoption. Most of the functionality is in the admin interface of the app that makes the website self sufficient, enabling rescue groups complete control over their adoption listings and process.

The PetRescue website receives ~200,000 pageviews per day and had nearly a decade of legacy data, making it a huge task to design and rebuild from the ground up, while maintaining integrity of the existing data. The app was heavily tuned for performance in the launch week, and the site also consists of import/export scripts and an API for various third party websites.

Overall the launch was a success, and PetRescue now have a much improved platform to help rehome the thousands of pets listed each month.

Visit the PetRescue website

Just Add a Dash of Include to Your Spinach

Posted in Agile Development, Inside TFG, Ruby on Rails, Tips and Tricks

Recently, I switched over from using Cucumber to Spinach in my Rails and mobile projects. I have been enjoying using Spinach so far and thought I’d share a pattern I’ve been using that seems to work for me.

Now I would like to preface this by saying that:

  • I’m not an expert on the topic
  • I’m not saying Spinach is better than Cucumber (or vice versa)

One of the things I found myself doing often when I was naming Cucumber steps was writing names that became very convoluted. I did this because Cucumber scopes all steps globally and naming two steps identically will cause the feature to fail with “Ambiguous match of “step name””. This meant I had to name almost identical steps slightly differently which would get compounded the more similar steps I had.

For example:

And I fill out the object create form with valid details
And I fill out the object create form with valid details using the google auto complete
And I fill out the object create form with valid details using the google auto complete and marking it as draft

When what I really wanted to say was:

And I fill out the form with valid details

All of that other information was covered in the feature name and/or scenario description.

When I moved to Spinach I found that I wasn’t having that problem because each feature’s steps were available only to that feature. I thought this was great… until I found myself defining identical steps in 20 different files.

My friend Tony Issakov then mentioned that you could define modules, include the Spinach DSL and share them between features. I was also warned, by my friend Jordan Maguire, that if you do this too much, you can end up with step definition files that are just includes and aren’t very readable.

For Example:

Feature: Updating an existing object

Background:
  Given I am logged in as an admin
  And there is an object in the system
  And I am on the object index page

Scenario: Successfully updating object
  When I click the object's name
  And I fill out the form with valid details
  Then I should be be on the object's show page
  And I should see the object's details have been update

Scenario: Failed to update object
  When I click the object's name
  And I fill out the form with invalid details
  Then I should see the form again
  And I should see any form errors
class UpdatingAnExistingObject < Spinach::FeatureSteps
  include SharedLinks
  include SharedPath
  include SharedForm
  include SharedObject
  include SharedViews
end

While this is an extreme example you can see that it quickly becomes difficult to know what step is defined where.

After a bit of playing around I found a happy balance between too much and too little step sharing. My general rule of thumb is to only share the following types of steps:

Authentication

module SharedAuthentication

  include Spinach::DSL

  Given 'I am logged in as an admin' do
    visit new_user_session_path
    user = FactoryGirl.create :admin
    login_with user.email, 'secret'
  end

  def login_with email, password
    fill_in 'user[email]', with: email
    fill_in 'user[password]', with: password
    click_button :submit
  end

end

Paths

module SharedPath

  include Spinach::DSL

  And 'I am on the objects index page' do
    visit objects_path
  end

  And "I am on the object's show page for my venue" do
    current_path.should == object_path(@object)
  end

  Then 'I should be on the objects index page' do
    current_path.should == objects_path
  end

end

Forms

Note that I don’t have any of the “And I fill in the form” steps in here. This is because I want separate them out and just have ‘And I fill out the form with valid details’ in my step definition.

module SharedForm

  include Spinach::DSL

  And 'I should see any form errors' do
    page.should have_css 'p.inline-errors'
  end

  def fill_in_object_edit_form attributes = nil
    if attributes.present?
      fill_in 'object[name]', with: attributes[:name]
      # fill in other attributes
    else
      fill_in 'object[name]', with: ''
    end
    click_button :submit
  end
end

Flash

module SharedFlash

  include Spinach::DSL

  And 'I should see a confirmation message' do
    page.should have_css 'p.notice'
  end

  And 'I should see a flash alert' do
    page.should have_css 'p.alert'
  end

end

Object creation

I generally like to have one per model that handles basic object creation.

module SharedObject

  include Spinach::DSL

  And 'there is object in the system' do
    @object = FactoryGirl.create :object
  end

  ## Where mk_two_object is another factory for Object
  And 'there is a mark two object in the system' do
    @mk_two_object = FactoryGirl.create :mk_two_object
  end

end

If we put it all together using the above example we get something that looks like this:
For Example:

Feature: Updating an existing object

Background:
  Given I am logged in as an admin
  And there is an object in the system
  And I am on the object index page

Scenario: Successfully updating object
  When I click the object's name
  And I fill out the form with valid details
  Then I should be be on the object's show page
  And I should see the details have been update

Scenario: Failed to update object
  When I click the object's name
  And I fill out the form with invalid details
  Then I should see the form again
  And I should see any form errors
class UpdatingAnExistingObject < Spinach::FeatureSteps
  include SharedPath
  include SharedForm
  include SharedObject
  include SharedAuthentication

  When "I click the object's name" do
    click_link @object.name
  end

  And 'I fill out the form with valid details' do
    @attributes = FactoryGirl.attributes_for :object
    fill_in_object_edit_form @attributes
  end

  And 'I should see the details have been update' do
    page.should have_content @attributes[:name]
    ## ...
  end

  And 'I fill out the form with invalid details' do
    fill_in_object_edit_form
  end

  Then 'I should see the form again' do
    page.should have_css "form#edit_object_#{@object.id}"
  end
end

Using this pattern I’ve found that I get the step separation that I was looking for in Spinach while keeping the shared functionality that I enjoyed in Cucumber.

I hope other people find this useful.

Search Posts

Featured Posts

Categories

Archives

View more archives