Hey There!

Hey, I’m Steve!  I’m a Senior Software Engineer at AppFolio.  I love creating, tinkering, and being inspired.

My Public Projects:

headyversion.com: a growing community focused around discovering the best versions of Grateful Dead songs

kind.fm: discover carefully curated spotify playlists from the best minds in independent radio

If you’re interested in collaborating on a project or sharing knowledgable, you can e-mail me at steve.klebanoff [at] gmail [dot] com.

Auto-post to Twitter and Facebook from Rails in 10 minutes

My newest project, kind.fm, automatically creates awesome Spotify playlists from track data entered into Spinitron.

Recently, I wanted to add some social integration into kind.fm.  Whenever a new playlist was added, I wanted to auto-post the new playlist to Twitter and Facebook.

The Hard Way

I have done some social integrations with Rails before, so I started thinking about how to do this.  It went something like this:

- Register new Twitter developer app- Store Twitter developer app credentials in Rails
- Using omniauth, generate authorization URL with proper credentials to get authentication token for twitter
- Store authentication token credentials in Rails
- Integrate rails callback to use client API gem to tweet every time new playlist is added
- Rinse and repeat above steps for Facebook
- Ensure callback uses a background job so it doesn’t slow the rest of the app down, and can be retried.

If you don’t already have a background job system yet, the last step is significant, even with the introduction of ActiveJob. You still need to decide on an adapter (Sidekiq? DelayedJob? Resque?), and most adapters require adding additional technology to your stack (i.e. Redis).

The Fast Way (~10 minutes)

I wanted to get this done quickly, and found a creative way to get this going in about 10 minutes, as opposed to the few hours the ‘hard way’ would take.

You may be familiar with services like Zapier and IFTTT.  These services allow you to setup tasks based on actions, i.e. “Whenever I post an instagram photo, re-post on my blog”.  It turns out you can leverage these services to easily perform simple social integration, by setting up a RSS feed of the things you’d like posted to Twitter and Facebook.

Here’s what I did:

First, I created an “index” action for my playlists_controller that outputs a RSS feed of social messages for the last 30 playlists. Based on params[:social] (either ‘facebook’ or ‘twitter’), I decide what message to output for the RSS feed.

# app/controllers/playlists_controller.rb
class PlaylistsController < ApplicationController
  def index
    @playlists = Playlist.active.includes(:show).where(
      show_id: Show.active.pluck(:id)
    ).order('played_on DESC').limit(30)
  end
 
end
# app/views/playlists/index.rss.builder
xml.instruct! :xml, :version => '1.0'
xml.rss :version => '2.0' do
  xml.channel do
    xml.title 'kind.fm playlists'
    xml.description 'discover inspired music'
    xml.link 'http://kind.fm'
 
    @playlists.each do |playlist|
      xml.item do
        xml.title "#{playlist.show.name} | #{playlist.played_on_formatted}"
 
        # choose description based on social media platform
        # uses custom functions on models, they might be better
        # suited for a helper though
        description = if params[:social] == 'twitter'
          playlist.twitter_description
        else
          playlist.facebook_description
        end
        xml.description description
 
        xml.pubDate playlist.played_on.to_s(:rfc822)
        xml.link playlist_url(playlist)
        xml.guid "playlist-#{playlist.id}"
      end
    end
  end
end

Now, it’s time to integrate the RSS feed with Zapier. I chose Zapier over IFTTT because it was easier to test out my integration.  First, I linked kind.fm’s twitter account and facebook account with Zapier. Then I set up two tasks:

When a new item appears on RSS feed http://kind.fm/playlists.rss?social=twitter, post to kind.fm’s twitter account

When a new item appears on RSS feed http://kind.fm/playlists.rss?social=facebook, post to kind.fm’s facebook profile

That’s it.  When a new playlist is added, the RSS feed reflects this.  Zapier is polling the RSS feed every 15 minutes, and when a new item appears, it posts to Twitter and Facebook with a custom message.

Thoughts & Caveats

There are definitely some caveats to The Fast Way, using RSS feeds and Zapier:

- Zapier’s free edition only allows for 100 tasks per month (that’s task actions, so in my case, 100 new playlists).
- Zapier hits your Rails server every 15 minutes, adding additional load, but especially if you throw some simple caching on top of your RSS feed this should be very minimal.
- Zapier only checks the RSS feed every 15 minutes, so there will be a slight delay between a playlist being added and the social messages going through.
- Zapier branding. On Facebook, there will some text saying “Posted via Zapier” on each post, but it is pretty small.  Also, on twitter, your links will be shortened with the zapier shortener, so they will look like zpr.io/s7LZ

There are benefits to the “The Hard Way”, and you’re also setting yourself up for integration with users to sign up using Facebook or Twitter.  But, if you are looking for a quick and easy solution, and you don’t mind the caveats, posting to Facebook and Twitter using Zapier may be a great way to go.

Know of any other good ways to integrate social posting into Rails? Let me know in the comments.

Shameless plug: If use Spotify and are looking for some good music to code to, check out No Jay’s House Of Watts on kind.fm

Simple invitation access code using Rails 4 & Devise

Want a user to provide a simple access/invitation code to register for an account using Rails 4 and devise?

See my github gist below. Supports having one dumb access code, nothing fancy. But, worth sharing: it’s not immediately straight forward how to do this.

This is achieved by:

- Setting up a virtual attribute on the user model called invitation_code

- Telling Rails strong parameters to allow invitation_code as an attribute on user when signing up

- Adds form field for invitation_code on the registration page

Opposite of chomp in Ruby

There does not seem to be an existing function which does the opposite of ‘chomp’ in Ruby in the standard library.

If you’d like to use a function to remove a specific substring from the beginning of a string, try this core extension.  Note: This doesn’t do any magic with whitespace as chomp does.

class String
def remove_from_beginning(string_to_remove)
len = string_to_remove.size
if self[0..(len-1)] == string_to_remove
return self[len..-1]
end
self
end
end

Facebook signed request losing session in Rails

Is the session in your Rails app getting messed up after a user goes to a facebook tab app  on your server and receives a signed request?

This can be happening because the facebook app doesn’t send a csrf token in it’s token. You can fix this by adding removing the protect_from_forgery callback on the facebook app’s action. See http://stackoverflow.com/questions/1177863/how-do-i-ignore-the-authenticity-token-for-specific-actions-in-rails

PgAdmin III fe_sendauth: no password supplied error

If you’ve set up a local unix postgres database that does not have a password, you may be able to connect via the console and your app but run into an error when connecting through PgAdmin3.

If you’ve got your pg_hba.conf correct and are still experiencing issues: try leaving the host field blank in the connection as opposed to using “localhost” or “127.0.0.1″. This tells PgAdmin to connect via the local unix socket instead of TCP.

CakePHP saving many objects with HABTM associations using saveAll

Saving many objects with their HABTM relationships using CakePHP’s saveAll is not as straight forward as one may think.

After playing around with results from $this->data, I’ve found the format that works.

In the example below, I’m saving multiple Users who have and belong to many Categories (HABTM). John belongs to Category’s 1 and 3, and Matthew belongs to categories 5 and 6.

Below is the array structure I passed to saveAll to get the save working.

Array
(
    [0] => Array
        (
            [User] => Array
                (
                    [first_name] => John
                    [last_name] => Smith
                    [email] => john@aol.com
                    [password] => fakepassword
                )
 
            [Category] => Array
                (
                    [Category] => Array
                        (
                            [0] => 1
                            [1] => 3
                        )
 
                )
 
        )
 
    [1] => Array
        (
            [User] => Array
                (
                    [first_name] => Matthew
                    [last_name] => Johnson
                    [email] => matt@aol.com
                    [password] => fakepassword
                )
 
            [Category] => Array
                (
                    [Category] => Array
                        (
                            [0] => 5
                            [1] => 6
                        )
 
                )
 
        )
 
)

Know of a better, more logical way? Please let me know in this comments. This structure doesn’t feel natural to me at all.

jQuery tools scrollable: Uncaught TypeError: Cannot set property ‘ontouchstart’ of undefined

I recently was getting the following error when calling .scrollable(); on a div using jQuery tools 1.2.5 and jQuery 1.4.4

Uncaught TypeError: Cannot set property 'ontouchstart' of undefined

My scrollable structure was set up in the following way:

    <div class="ss_scrollable">
        <div class="ss_items">
                    <div class="item_set">
                          <img src="item_one.png"/>
                    </div>
                    <div class="item_set">
                          <img src="item_two.png"/>
                    </div>
        </div>
        <a class="prev browse left" href="#" onclick="return false;"></a>
        <a class="next browse right" href="#" onclick="return false;"></a>
    </div>

I was able to fix the error by moving the next and previous links outside of the ss_scrollable div.

Uploadify stalling on uploads on Internet Explorer 8

For some reason, calling .hide() on my #uploadify div was causing uploads to stall after the #uploadify div was shown.

Very strange bug, eh? The hacky solution is instead to use div.height on #file_uploadUploader instead of .hide() and .show() on #uploadify

// To hide uploadify
$("#file_uploadUploader").height(0);
 
// To show uploadify
$("#file_uploadUploader").height(30);

If you want to hide #file_uploadUploader when the page loads, use the onSWFReady callback.

Hope this saves someone a headache.

Galleriffic IE 7 Fix: Images not showing

I had an issue where Galleriffic was not displaying the current image correctly. Searching around, it seems like others have had this issue as well.

The fix for me was simple, I just added the following to my CSS and it worked:

div.slideshow img
{
    position: relative;
}