Text

Rspec and Devise Invitable create password integration test

If you want to test a devise invitable set password page like I did, since I was allowing users to set other attributes there is a little trick to it. You need the session for the url. Here is how to get it.

You will need to call invite on a customer, make sure it is not commited to the db. Then the user will have a raw_invatation_token attr you can pass to the url.

    
  describe "Setup Customer after invite (test what is not tested in invitable plugin)" do
    before do
      customer_invited.invite!
      visit accept_customer_invitation_path(customer_invited, invitation_token: customer_invited.raw_invitation_token)
      fill_in "Password", with: "password"
      fill_in "Password confirmation", with: "password"
      fill_in "User name", with: "new user name"
      click_button "Set my password"
    end
    it { customer_invited.reload.user_name.should eq("new user name")}
  end
Text

Shopify Starter

I have been doing some shopify work lately and I have found the workflow to be a bit hard to fit into my style. I wanted to be able to quickly setup a local dev environment with some of my favorite tools so I created this shopify starter to get things up and running in a familiar fashion quickly. Hope some one finds this helpful. https://github.com/gwincr11/shopify-starter

Includes:

  1. Bower - for js package managment http://bower.io/
  2. Grunt - to run processes like jshint, compass, live reload etc.. http://gruntjs.com/
  3. Bootstrap 3 - don’t just use it on its own it is a framework :) http://getbootstrap.com/
  4. Watch with Live reload - Runs all the grunt tasks and reloads the webpage once upload to shopify is completed. https://github.com/gruntjs/grunt-contrib-watch
  5. Compass - This Sass add on comes with sass and a bunch of helpers to make your life easier.http://compass-style.org/
  6. Grunt Shopify - Once configured this will upload the updated files to shopify. https://github.com/wilr/grunt-shopify
  7. Shopify Skeleton theme - The skeleton template theme is included although slightly altered to work with above technologies. https://github.com/Shopify/skeleton-theme
  8. Grunt modernizr - Custom modernizr build based on what your are usinghttps://github.com/Modernizr/grunt-modernizr
  9. jshint - offers useful advice about how to improve your js https://github.com/gruntjs/grunt-contrib-jshint
  10. grunt concat - concatinates all js files into a single file - https://github.com/gruntjs/grunt-contrib-concat
  11. grunt concat bower - same thing but understand bowers folder structure - https://github.com/sapegin/grunt-bower-concat
  12. grunt uglify - minimizes your javascript - https://github.com/gruntjs/grunt-contrib-uglify
Link
Link

I wanted to try my hand at some html css art. So here is my Marvin the Martian which I loved to draw as a kid.

Text

Javascript debouncer

Sometimes when attaching callback functions to event you want to make sure that the event doesn’t fire a whole bunch of times while the event is occurring consistently. A technique to stop this from happening is debouncing. Debouncing is actually a term borrowed from electronics that keeps a circuit from firing more then once. To do this in js use the following function

//Makes sure an event is not still occuring before firing the callback
//for example, if a window is being resized it may call the resize event multiple
// times
function debouncer( func , timeout ) {
  var timeoutID , timeout = timeout || 200;
  return function () {
    var scope = this , args = arguments;
    clearTimeout( timeoutID );
    timeoutID = setTimeout( function () {
      func.apply( scope , Array.prototype.slice.call( args ) );
    } , timeout );
  };
}

You can then add it to a function call like so

$(window).resize(debouncer(function() {
  $(‘.centerme’).centerMe();
}, 200));

Text

A simple rails state machine

So I need functionality like a state machine but all the state machines out there where way more then what I need. Essentially I just need to be able to send emails when the status of a case switches from one state to another. Turns out active record has a pretty great little tool to assist with this called Dirty. http://apidock.com/rails/ActiveRecord/Dirty

Now before you jump to some Miley Cyrus joke here is what it does.

You can check what a attribute_was, if attribute_changed? and a before and after array with status_change. These brilliantly named method make building a simple state transition checker rather straight forward.

1. create your function checking the change.

def starting_work?
  if self.status_change == [“new”, “in_progress”]
    return true
  else
    return false
  end
end

2. Then you can use the method as a condition on a callback function:

after_save :email_warranty_assigned, if: :starting_work?

3. Profit.

In it’s purist form this is not a proper state machine as it does not prevent things from transferring to the wrong state. But that was functionality I did not require.

Text

Active Admin, semantic_form_for, and has_many

I have been working with Active Admin on my latest project and one of the requirements that lead to me choosing Active Admin was the ability to create custom forms. Let me begin by saying for any basic content manipulation active admin is great. It has a DSL built on top of formtastic for building custom forms in the admin. The combination of this and the boilerplate admin setup really speeds up development. However there are some gotchas along the way. Currently I have been dealing with one and I thought I would document what I have found so far.

In this particular scenario I was building out a custom form from a partial. I want the ability to have swf upload move data to a temp s3 bucket and add records to a has many relationship. So what I am building is as follows:

1. When creating a new Marketing Media item the user uploads many files to a temp s3 bucket.

2. When each file upload completes a js callback adds a new relationship of type Advertising Entity to the currently selected Marketing Media. Allowing for multiple files to be added.

3. When saved the Marketing Media entity saves each of the related Advertising Entity elements which sets up a queue to move the items to a final url on s3, this url is being maintained by paperclip.

Ok this is a fairly unique set of form requirements. All of the queuing and transferring of files is being taken care of by the models and rails delayed job.

Marketing Media model:

class MarketingMedia < ActiveRecord::Base

  validates :title, presence: true, length: { maximum: 140 }
  validates :body, presence: true

  has_attached_file :image, styles: {
    small: “150x150>”,
    medium: “300x300>”,
    large: “600x600>”
  }

  has_many :advertising_entities, dependent: :destroy
  accepts_nested_attributes_for :advertising_entities,
    :reject_if => lambda { |attributes| attributes[:file_file_name].blank? },
    :allow_destroy => true
  acts_as_ordered_taggable
end

Advertising Entity Model:

require ‘aws’


class AdvertisingEntity < ActiveRecord::Base
  belongs_to :marketing_media
  include Expirable
  acts_as_ordered_taggable

  has_attached_file :file

  validates :body, presence: true
  validates :title, presence: true, length: { maximum: 140 }

  # setup the needed file attributes for paperclip
  before_create :set_upload_attributes
  # setup delayed job to move the file.
  after_create :queue_processing

  # Set attachment attributes from the direct upload
  # @note Retry logic handles S3 “eventual consistency” lag.
  # this sets all the things that paperclip needs to work with an
  # attachement.
  # pass in s3 so it can be mocked out.
  def set_upload_attributes(s3=AWS::S3.new(:access_key_id =>       ENV[‘AWS_ACCESS_KEY_ID’],
  :secret_access_key => ENV[‘AWS_SECRET_ACCESS_KEY’]) )
    return true unless file_file_name != “”
    # amazon fails try multiple times
    tries ||= 5
    # get our file
    direct_upload_head = s3.buckets[ENV[‘AWS_TEMP_BUCKET’]].
    objects[file_file_name].head
    #set up all the file information
    self.file_file_name = file_file_name
    self.file_file_size = direct_upload_head.content_length
    self.file_content_type = direct_upload_head.content_type
    self.file_updated_at = direct_upload_head.last_modified

    # retry logic
    rescue AWS::S3::Errors::NoSuchKey => e
      tries -= 1
    if tries > 0
      sleep(3)
      retry
    else
      true
    end
  end

  # Delayed job tha asynchronously moves the media image to its final   destination and
  # deletes the temp file. based on:
  # http://blog.littleblimp.com/post/53942611764/direct-uploads-to-s3-with- rails-paperclip-and
  # pass in s3 so it can be mocked out.
  def self.transfer_and_cleanup(id, s3 = AWS::S3.new(:access_key_id =>      ENV[‘AWS_ACCESS_KEY_ID’],
  :secret_access_key => ENV[‘AWS_SECRET_ACCESS_KEY’]) )

    #get the asset to manipulate
    document = AdvertisingEntity.find(id)

    #setup the final file path… we need to get rid of the first slash or it wont move properly.
    paperclip_file_path = document.file.path[1..-1]

    #copy the s3 file from its temp position to its final position
    bucket1 = s3.buckets[ENV[‘AWS_TEMP_BUCKET’]]
    bucket2 = s3.buckets[ENV[‘AWS_BUCKET’]]
    obj1 = bucket1.objects[document.file_file_name]
    obj2 = bucket2.objects[paperclip_file_path]

    response = obj1.copy_to(obj2, :acl => :public_read)

    # flag it as moved
    document.processed = true
    # save the changes
    document.save

    #delete the temp file.
    obj1.delete
  end

  # Queue file processing
  def queue_processing
    AdvertisingEntity.delay.transfer_and_cleanup(id)
  end
end

The trouble spot. After working with the form builder a while I was running into a number of problems creating this form. Their is some well documented oddness with the way the Active Admin Form Builder DSL and the Formtastic DSL work together. It seems that in some cases the form will be drawn twice. Lets take a look at my code and see what has led to my solution so far.

<div id=”main_content”>
<%= semantic_form_for [:admin, @marketing_media],
:url => admin_marketing_medium_path(@marketing_media), builder: ActiveAdmin::FormBuilder do |f| %>
<% f.semantic_errors :state %>
<% f.inputs :name => “Description” do %>
<% f.inputs :title %>
<% f.inputs :body %>
<% f.input :tag_list, :hint => ‘Comma separated’ %>
<% f.has_many :advertising_entities, :heading => ‘media’,
:allow_destroy => true do |p| %>
<% p.input :id, as: :hidden %>
<% p.inputs :title %>
<%= p.inputs :body %>
<%= p.input :temp_url, as: “hidden”, id: “temp_url” %>
<%= p.input :file_file_name, as: “hidden”, id: “file_name” %>
<% end %>
<% f.actions :commit %>
<% end %>
<% end %>

<div class=”uploader”>
<h1>Uploader</h1>
<div id=”file_lists”>
<ul id=”file_done_list” class=”file_list”></ul>
<ul id=”file_todo_list” class=”file_list”></ul>
</div>

<div id=”queue_size”></div>

<div id=”overall”><span class=”progress”><span class=”amount”>10%</span></span><span id=”status”></span></div>

<% raw s3_swf_upload_tag(
file_size_limit: “1000MB”,
file_upload_limit: 5,
queueSizeLimit: 1,
:onFileNotInQueue => “alert(‘File not found in the queue’);”,
:onFileSizeLimitReached => “alert(‘That file is too big’);”,
:onQueueChange => “queueChangeHandler(queue);”,
:onQueueSizeLimitReached => “alert(‘There are too many files in the queue’);”,
:onQueueEmpty => “alert(‘You gotta have at least one file in there’);”,
:onQueueClear => “queueClearHandler(queue);”,
:onUploadingStart => “uploadingStartHandler();”,
:onUploadingFinish => “uploadingFinishHandler();”,
:onSignatureIOError => “alert(‘There was an error’);”,
:onSignatureXMLError => “alert(‘There was an error’);”,
:onSignatureSecurityError => “alert(‘There was an error’);”,
:onUploadError => “alert(‘There was an error’);”,
:onUploadIOError => “alert(‘There was an error’);”,
:onUploadSecurityError => “alert(‘There was an error’);”,
:onUploadProgress => “progressHandler(progress_event);”,
:onUploadComplete => “uploadCompleteHandler(upload_options,event);”
) %>
<button id=”uploadmedia”>Start Uploading</button>
</div>
</div>
<%= javascript_include_tag “swf_upload_config” %>

Some note worthy things here.

1. Only the semantic_form_for tag has a = sign in the erb call. (well almost more on this later) It seems that if you put in the = sign for each and every block you run into duplicate rendering issues. For some reason their are two calls for each input area. This issue is talked about a lot on the github issues area for active admin 

https://github.com/gregbell/active_admin/issues/2401

https://github.com/gregbell/active_admin/issues/2189

https://github.com/gregbell/active_admin/issues/333

2. The custom html comes after the form. This one really bothers me, the whole reason I choose active admin was for custom html. However if you put custom html in with the form builder code it will do a few different things, it may display no content at all, it may duplicate content or it may show only some content. I have not dug in enough to understand the triggers foreach of these.

3. Their are not any empty lines in the form builder code. This is also a little annoying, it seems if you put empty lines in the wrong place then nothing will display. 

4. Inside the has_many block issue one seems to go haywire. For some reason the first two elements <% p.input :id, as: :hidden %>, <% p.inputs :title %> will display twice if there is an = but the other elements in this block will not display at all. 

I hope this helps some one some where with active admin forms. I am finding experimentation is the best path forward as currently my understanding of the three form builders (FormBuilder < ::Formtastic::FormBuilder < ActionView::Helpers::FormBuilder) work together is complicated at best.

I am continuing to use active admin as it help with a lot of boilerplate but sometimes it is weird. 

Text

Setting up a rails 4 application quick self reference

Here is a quick outline I put together for my self to remind my self how to setup a new rails project.

  1. cd to directory.
  2. rails new [app name] -T #no test suite flag
  3. Create RVM files .ruby-gemset, name in file and .ruby-version, version of ruby to use
  4. Setup basic gems
    source 'https://rubygems.org'
    ruby '2.0.0'
    # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
    gem 'rails', '4.0.0'
    gem 'pg', '0.15.1'
    
    group :development, :test do
    gem 'rspec-rails', '2.13.1'
    end
    
    group :test do
    gem 'selenium-webdriver', '2.35.1'
    gem 'capybara', '2.1.0'
    gem 'guard-rspec', '2.5.0'
    gem 'spork-rails', '4.0.0'
    gem 'guard-spork', '1.5.0'
    gem 'childprocess', '0.3.9'
    gem 'factory_girl_rails', '4.2.1'
    gem "launchy", "~> 2.1.2"
    end
    
    gem 'sass-rails', '4.0.0'
    gem 'uglifier', '2.1.1'
    gem 'coffee-rails', '4.0.0'
    gem 'jquery-rails', '3.0.4'
    gem 'turbolinks', '1.1.1'
    gem 'jbuilder', '1.0.2'
    
    group :doc do
    gem 'sdoc', '0.3.20', require: false
    end
    
    group :production do
    gem 'rails_12factor', '0.0.2'
    end
    
  5. bundle install
  6. Setup config->database.yml
  7. rake db:create
  8. rake db:migrate
  9. rails g rspec:install
  10. Setup guard and spork:
  11. http://ruby.railstutorial.org/chapters/static-pages#sec-guard
  12. Add factory girl file spec->factories.rb
  13. Setup focused rspec tests: spec->spec_helper.rb
    RSpec.configure do |config|
    .
    .
    .
    config.mock_with :rspec
    config.filter_run :focused => true
    config.alias_example_to :fit, :focused => true
    config.run_all_when_everything_filtered = true
    .
    .
    
Text

Expression Engine on Pagoda Box

Picking a hosting environment is always a tricky task. There are so many options these days it is hard to know what to choose. For my latest Expression Engine projects I have been trying Pagodabox and have been happy with the choice.

Pagodabox is a PAAS (platform as a service) php hosting environment. This is nice because they let you scale each piece of the service independently, want to add more servers just slide a slider in the web interface and a new instance is spun up and load balanced. Pagodabox also offers the ability to push changes to the site with a git workflow, and maintains all branches and version. If you need to tweak any of the PHP servers setting they have a yml config file (.boxfile) that will load allowed libraries and setup other php settings.

The Pagoda gem is another super handy feature. This tool lets you check log files, tunnel into databases, and even scale from the command line. Finally they offer SSH connections to shared directories to make it easy to get into certain parts of the file system.

Getting setup is pretty easy, I actually followed a handy tutorial by The Good Lab  this got me up and running. I then setup automatic DB backups to s3 using this script 

The thing I struggled with the most is the shared writable directory setup. I kept running into little bugs like captchas not showing up. This was an issue with my shared dir setup every time. Make sure you upload all required writable directories and that they are set to 777. What I did was to ssh into the shared file and check to see if things where there if not I either made them with the command line or copied them over. 

Above and beyond this I would also point out that it is a great place to host your site because you can get a lot for free, this is really beneficial to me as I have been able to setup dev environments for each site I am building with no cost and I can tunnel the production database and the dev database to each other to sync changes.

Text

A manifesto

This morning I was thinking about what my web design manifesto would be, here is what I came up with.

I believe in websites that get out of the way of users and showcase information, products or capabilities. Websites are canvases used for delivering objects, or enabling actions. As a web developer/UX preacher it is my job to organize those canvases so you can find, understand and use these canvases. Whenever possible to do this I try to gain empathy for user needs, present solutions to problems and constantly test these hypothesis until the largest possible audience is pleased.