Archive for category: Rails

Extending Rails Engins with the Decorators Ruby Gem

14 Apr
April 14, 2013

Over the past month I have been launching a few sites using a neat little Rails engine called Piggybak. Piggybak (worth a blog post on its own) handles just the basics of an e-store, and leaves the rest up for the creative developer.

While building these sites I would run into scenarios where I needed to extend the engine’s functionality and I went searching for an elegant “railsy” way of doing so. My search led me to some threads from the Forem project, and ultimately to the Decorators gem.

RTFM

I couldn’t readily find any how-to’s on the gem so I dug into the code, and the usage in the Forem gem. It is super simple to use, but I figured I would add some documentation here on the blog. First things first, to utilize Decorators in your rails project add it to your Gemfile

gem 'decorators'

The gem does have some opinions on how one should construct their decorators for Rails engines. I based my usage upon what was found in Forem and created a decorators folder in the app root of my Rails.root. Within that folder, one should then create folders that mimic your extensions/decorations to engines (i.e. /app/decorators/models, /app/decorators/views etc), and the decorators themselves need to have a suffix of _decorator.rb.

Decorate

So lets decorate the Piggybak::Order model to include an association for packages. Following the folder structure above, we would create a file at /app/decorators/models/piggybak/order_decorator.rb like so:

Initialize

The last piece to take care of is add the following line to a config/initializer file:


Decorators.register! Rails.root

Crowd Sourcing E-Commerce Photos

21 May
May 21, 2012

There is no longer any doubting the power of mobile phones, and in particular the ability to rapidly share photos with hipster-esque filters applied. After all, we can all cite theone billion$reasons for this.

So when the idea was hatched at thelongboardstore.com to add in some social photo aspect to our site, I was very excited to bring the functionality to life.

Photos By The People, For The People

The concept is rather simple – tap into the massive growing user base of Instagram, and our customer’s mobile devices to power photos for the website. A majority of our customers are in the younger crowd, so why not give them a way to post pictures of what they love – their longboards.

Instagram Photos in Product Detail Page

So all a friend of thelongboardstore.com needs to do is tag any photo with #thelongboardstore within Instagram, and the rest is Rails/Instagram API magic.

Some Code, Some Moderation

To implement the new feature, I leveraged the `official` Instagram ruby gem:

#Gemfile
gem "instagram"

And depending on how you roll with your configuration options, simply add something like so:

#/config/initializers/instagram.rb
Instagram.configure do |config|
config.client_id = "z0mgcl13nt1d"
config.access_token = "s3cr3ts4u1r3ll"
end

For data modeling, I setup a has_many through relationship for Instagram media to our `Product` model. This allows a given photo of a longboard, or a truck, to be attached to many products on the public-facing side of our website. Super social huh?

With all that in place, the process of fetching photos from the Instagram API to persist in our system is so simple it hurts:

instagrams = Instagram.tag_recent_media('thelongboardstore', {:min_tag_id => @last_import_min_tag_id})

The min_tag_id option is a timestamp of sorts that Instagram passes back in their response. This allows the developer to specify a point in time to search for photos.

I iterate over the result set, and add the new photos into a moderation queue in our Admin interface… because you can’t always trust people to do the right thing, and it allows us to attach photos to products.

In Moderation

In-House Efficiencies

The perks of the social photo aspect are obvious for our site visitors. It gives them a way to share their stoke with us, and the rest of the community, and it offers a great glimpse at our products in-action… in a way its almost as good as an in-depth review of the board.

One other awesome thing that has come of the new system though is how we are using Instagram in-house for adding detailed photos to our products. We currently shoot all of our own product photos at the shop – stock photos are just so, well meh. But now, any person in the shop can take a few snapshots of a deck from a different angle, or a close up detail shot of a graphic and add it to the site.

The process is extremely fast, and really fun as well. In the first day alone, two folks at the shop added close to 100 photos. One Hundred. In a single afternoon.

I’m curious to see how our customers start using the system. This morning there were a dozen or so pictures in the queue from them. Furthermore, the Instagram API option of subscribing to tags or geographic areas has got me thinking of a few other applications to use with the service.

Omniauth and Facebook’s #_+_

23 Apr
April 23, 2012

I’m in the process of implementing a new review system for thelongboardstore.com and am using Omniauth to allow users to sign on via their Facebook account. All is happy and well, but there is a known issue with Facebook where they append ‘#_+_’ to url’s when redirecting a user back to your application.

Being foolish stubborn, I attempted various work-arounds for this one… up to and including nginx re-writes, rack middleware, and cursing. In the end, the functioning work-around is to follow the advice at stackoverflow and reset the hash via javascript:

window.location.hash = ""

As such in my implementation, I have set an instance variable to determine if the user is being redirected from Facebook, and redirecting them upon page load to a new page where the #_+_ doesn’t totally tank my JS:


<% if @show_review -%>
if(window.location.hash.length > 0){
window.location.hash = '';
window.location.href = "<%= @product.url %>?review=1";
}
<% end %>

Ghetto, hack, ugh.