We create positive world change connecting authentic companies with real people in socially responsible ways.

Unicorn

How to Get a Month Name from a Month Number in Ruby

June 08, 2010 by Brandon Weiss

Today I had a need to get the name of a month by its number. So if I had the number ‘6’ I would want to be able to get ‘June’.

This is not a particularly complicated problem; there are myriad ways to accomplish this, but all of them are rather kludgey, and Ruby being such a magical language I was sure there must be a method built-in. Or at the very least there would be a helper for it in Rails.

But after checking the docs for both I couldn’t find anything. Google also returned nothing except the kludgey ways I already knew how to do. So I gave up and wrote this:

month = 06
date = Date.parse("2010-#{month}-01")
month_name = date.strftime("%B") # => "June"

As I said it’s very simple to do, but seems so unnecessarily roundabout. Parsing a string to a Date object and then using the date formatter method to get the name? That doesn’t smell anything like Ruby.

I could create my own array or hash to map them, which is slightly more elegant, but more lines of code, and still rather roundabout.

So I took one more look at the docs, and while I was reading them it occurred to me that if the strftime method can do it, Ruby must have some internal way of mapping month numbers to names. So I took a look at the actual source for strftime and found the answer.

Although I’ve been to the doc page for the Date class hundreds of times, I’d never really used it except to reference particular methods, so I’ve always just skipped right by the constants section at the beginning. But in it there’s a MONTHNAMES constant, and on the first line in the section, no less.

So to get the month name from a number, all you have to do is1:

Date::MONTHNAMES[6] # => "June"

Ruby really is made out of unicorns.

1 As an added bonus, since arrays start with 0, they’ve shifted the array values up one by starting the array with nil at index 0, so you can get the actual month name of a number without having to manually subtract 1 from that number.

Comments

Paperclip

How to Migrate from Attachment_fu Filesystem to Paperclip S3

March 02, 2010 by Brandon Weiss

The biggest hurdle in my quest to get our site running on Heroku turned out to be asset uploading. Because of the way Heroku is architected, each application instance is read-only. You cannot just upload files and write them to disk, and even if you could, they would only be available to the instance you uploaded them to; none of the others would be able to see them.

Heroku is cloud-based hosting, so the solution is cloud-based storage. Any service will do, but I’d recommend Amazon S3. If you aren’t using it already, now is as good a time as any to switch. The benefits of having a fast, scalable storage system in the cloud are almost too many to count.

Unfortunately our site wasn’t using S3 yet, so the first step was to migrate all the uploaded assets to it. Luckily, if you’re using a file attachment library like Paperclip (which we are), that part is actually pretty easy.

Paperclip filesystem to Paperclip S3

To start, create an s3.yml and put it in config/. Here’s what’s in mine:

access_key_id: xxxxxxxxxxxxxxxxxxxx
secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
bucket: firebelly

If you like, you can also specify different accounts/buckets for development and production like you do for databases.

Then in your model change your attachment method from something like this:

has_attached_file :photo

To this:

has_attached_file :photo,
  :storage => :s3,
  :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  :path => ":attachment/:id/:style.:extension"

Then migrate the files themselves over to S3, and either change the structure to match your :path, or change the :path to match your directory structure. Be sure to set the access permissions correctly; you want Read set for all users, or the files won’t be viewable. Future file uploads will have permissions automatically set by Paperclip, but when you upload them manually the permissions must be set manually as well.

The Plot Thickens

I thought I was done, but then I saw it, lurking in the corner: attachment_fu. Some of our models were sadly still using attachment_fu, and while there’s nothing necessarily wrong with attachment_fu, Paperclip is just more modern and has become the de facto standard for file attachments. Plus, we definitely shouldn’t be using two different libraries in the same app; that’s just ugly. So I have to migrate all the models using attachment_fu to use Paperclip instead.

I had a feeling this was going to be really, really painful, so I hit up Google first to see if maybe someone else had written about it and I could save myself some trouble. But surprisingly, even though many people must have done this before me, I could only find one halfway decent guide for migrating from attachment_fu to Paperclip written by James Stewart. And just my luck, it didn’t work for me. I’m sure it must be something related to my particular setup, because it seemed to work for everyone in the comments, but I just got a bunch of errors that I couldn’t figure out. So instead I hacked James’ script to get around the errors. Here’s what I did:

Attachment_fu filesystem to Paperclip S3

First, grab a copy of the Paperclip migration script that I forked and modified (yay, GitHub) and put it in lib/.

Now make a new migration:

script/generate migration convert_project_slides

And edit it:

class ConvertProjectSlides < ActiveRecord::Migration
  include PaperclipMigrations
  
  def self.up
    add_paperclip_fields :project_slides, :photo
    
    ProjectSlide.reset_column_information
    
    ProjectSlide.all.each do |project_slide|
      populate_paperclip_from_attachment_fu(project_slide, project_slide, 'photo', '/project_slides/')
    end
  end
  
  def self.down
    remove_paperclip_fields :project_slides, :photo
  end
end

Let me break down what’s happening in this migration.

  1. You have to include the paperclip_migrations.rb script in your migration.
  2. Then the columns Paperclip uses need to be added to the project_slides table.
  3. The arguments that have to be passed to populate_paperclip_from_attachment_fu is where I got a little confused. The first one is the model you’re sending to, the second is the attachment you’re sending from. In this case they’re the same thing. The third one is the prefix you specified in add_paperclip_fields, and the fourth is the directory where the attachment_fu files are.

The original script didn’t have that fourth argument because it can be gotten from attachment_fu, but inexplicably that wouldn’t work for me, so I had to disable attachment_fu and specify it manually.

But before you run the migration, you have to take out attachment_fu’s has_attachment declaration in your model. Now would also be a good time to replace it with Paperclip’s declaration. So just like before, something like this:

has_attachment :content_type => :image, 
  :storage => :file_system,
  :path_prefix => 'public/project_slides',
  :resize_to => '345x285>',
  :thumbnails => { :thumb => '135x135!' }

Becomes something like this:

has_attached_file :photo,
  :styles => { :thumb => '135x135!' },
  :storage => :s3,
  :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  :path => ":attachment/:id/:style.:extension"

One more thing before you run the migration. When attachment_fu creates thumbnails I guess the way it links them back to the original is by creating a new record in the table, and referencing the original record in a parent_id column, creating a tree structure. But I only want the migration to run on the original attachments, not thumbnails, so I deleted them from the database with something like:

DELETE FROM project_slides WHERE parent_id IS NOT NULL

That SQL query will delete any rows that have a value in the parent_id field (which means they aren’t originals).

OK, all set, now you can run the migration:

rake db:migrate

Assuming everything worked, you might want to drop attachment_fu’s various columns from your table. The ones I had were:

size
content_type
filename
height
width
parent_id
thumbnail

Lastly, just upload the photos to S3 like before, set the permissions and you’re done.

Comments

Wargames-wopr

The True Cost of Servers

February 19, 2010 by Brandon Weiss

I talk about this all the time, but it bears repeating: servers are expensive. They might seem so cheap up front, but once you factor in average maintenance time the actual cost could easily be a thousand dollars a month, if not more, a fact I lamented in a breakdown of the different types of hosting here a few months ago.

Unfortunately, my breakdown didn’t really have any hard numbers because I don’t keep track of task types when I freelance, and I don’t keep track of time at all on my personal projects. But at Firebelly we do, and now that I’ve been here long enough to get a good sample, I decided to run the numbers.

In the past 5 months I’ve spent 42 hours on server maintenance. That is, frankly, insane. That’s thousands and thousands of dollars worth of time. And that doesn’t even factor in back-end development work that had to be done as a result of having physical servers, like having to convert our asset uploads to use Amazon S3 because the server ran out of space (something I’ll get into in a later post). So 42 hours could easily be a conservative estimate. I wouldn’t be too surprised to see the true cost of our servers over 5 months exceed $10,000. Which is an obscene amount of money and the reason I’m so interested in cloud hosting.

In the breakdown I mentioned that Heroku might be the holy grail for Ruby hosting, but I didn’t have any direct experience with it, so it was really all just theoretical. But that was three months ago. Since then I’ve migrated all my personal projects to use Heroku.

Transitioning between hosts is a normally excruciatingly painful process, but moving to Heroku was actually fun. The whole process only took about a half hour for each project and went off virtually without a hitch. The only hiccup was a few differences in syntax between MySQL and PostgreSQL (the database Heroku uses), but that took less than a few minutes to fix, and after that it was all smooth sailing.

Now that I’ve experienced Heroku first-hand, the next step is to move Firebelly projects over, starting with our main site. I’ll recap in a few months after it’s done to report on how it went and how much time it’s saved us.

Comments

Haiti

Direct Help For Haiti

January 15, 2010 by Dawn Hancock

Below is a letter directed to me from one of our clients and dear friends of the studio. Please do what you can. Immediate action is so important right now! I assure you this is legit. We will be sending supplies. If you would like to join in with us, please let us know.

Dear family and friends,
I am certain that many of you, like me, are struck dumb by the tragedy in Haiti. I think we must not allow ourselves to be like that. Rather, we must act and mobilize in all the ways that we can. Below is a message from a dear Haitian friend of mine, Daphne Sajous. She and her husband are like family for me. I know her commitment, her family’s commitment and their integrity. Please respond in any way that you can to the multiple (and all reliable) avenues for response that Daphne outlines in her message. Also, please drop she and her family an email of solidarity when you can.

Thank you.
Luta.
Prexy

From: Daphne Sajous-Brady daphnesb@rcn.com
Date: January 15, 2010 12:57:31 AM CST
Subject: Family Update

Dear Family and Friends,
Thank you all for the phone calls and emails asking about my family in Haiti. Your concern, thoughts and prayers have meant a lot.

It is nothing short of a miracle that all of my closest relatives are unharmed. For the most part, they live and work in the heart of the damaged areas. Many of the places they frequent (and ones that I’ve frequented) have been brought to the ground. As a family, we were also very fortunate to have news that my grandmother, aunts, uncles, and cousins were fine the night of the earthquake. Facebook and e-mail have been invaluable. Now, my parents call me to see what has been posted on facebook. Since the initial relief that our close relatives are okay, news has been trickling in about good family friends who are either confirmed dead or are missing.

My family still does not know the extent of the damage and their businesses, children’s schools, etc. Some of their homes are not structurally sound and one uncle’s business is gone. Several of my mother’s brothers and sisters live together on a hill, like a small family compound, in Freres, a suburb of Port-au-Prince. Those homes are intact, but due to aftershocks and uncertainty regarding unseen damage, they have been sleeping outdoors, either in their cars or on porches/decks.

Two of my mother’s sisters have a school in Petionville, another suburb of Port-au-Prince. The school grounds have become a haven for approximately 40 people and school employees and their families who have lost their homes. Because lunch is normally served to the children who attend the school, there are large food provisions. For the moment, my family is not too worried about food because of these reserves.

As many of you may know, my grandmother has a hospital and she along with a few others established it and run it. The hospital is not far from the family compound, and since the earthquake, most of my family members (young, old, doctors and non-doctors alike) have been spending their time there. They have been working tirelessly, but due to the great number of wounded and limited supplies, they have watched many people die. They are currently working with very few supplies. Sheets and blankets from their own homes are being used for bandages and beds.

A second cousin of mine, who normally lives in Miami, is currently doing journalism work with CNN, and he’s helped put my grandmother’s hospital on Sanjay Gupta’s radar, which may draw greater attention to the hospital’s needs. Also, other family members have been contacting organizations in DC to make sure they deliver medical supplies to the hospital when they arrive.

Stateside, I, along with my sister and cousins, have been coordinating efforts to send supplies to the hospital. One cousin, who is in the navy, is organizing a group of military doctors who will enter Haiti through the Dominican Republican. They will deliver supplies and provide services to hospital. Another cousin is a pilot, and he is prepared to use his small plane to make trips from Miami to Haiti with supplies for the hospital.

Many of you have asked if there is anything you can do. Donating money to organizations like Doctors without Borders and UNICEF would be wonderful. If you want to support our family’s efforts to bring supplies to my grandmother’s hospital, Hopital de la Communaute Haitienne, that would also be greatly appreciated. It has functioning ICU and accepts tax deductible checks at the following address:

Haitian Health and Education Foundation
c/o Lynx Air Int’l PO Box 407139
Ft. Lauderdale, FL 33340-7139

Also, supplies can be sent to the following address:

Robert Hare
19731 SW 89 Ave
Miami, Fl. 33157

This is a cousin’s home address where we are gathering goods to be piloted by another family member to Haiti.

This is what is needed:

1. Basics – sheets, blankets, mattresses, food, water, clothes, large garbage bags, cleaning supplies
2. Medical – gauze, wound dressings, large bandages, fluids (e.g., saline), IV fluids, pain medication, needles, antibiotics (e.g., ointment, IV, pills), alcohol/alcohol wipes, any orthopedic care supplies

This has been a very difficult time for me, so I appreciate all of you reaching out. I will keep you posted on any new developments.

Love to all of you,
Daphne

Daphne Sajous-Brady, MA
Learning Specialist
Doctoral Candidate
Communication Sciences & Disorders
Northwestern University

Comments

image placeholder

Creative Genius

January 04, 2010 by Brandon Weiss

A while ago I watched a fantastic TED talk by Elizabeth Gilbert about creative genius and the way it used to be perceived compared to how it’s perceived now. Here it is:

I’d actually forgotten about it until I came across a blog post by Seth Godin quoting Diablo Cody on the pressure to outdo herself.

Then I forgot about that too until today when I remembered and figured I should post it before I forget again.

Comments

previous page