<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Brandon Weiss's Posts - Firebelly Design</title>
    <link>http://firebellydesign.com/</link>
    <description>Socially conscious design.</description>
    <item>
      <title>How to Get a Month Name from a Month Number in Ruby</title>
      <author>brandon@firebellydesign.com (Brandon Weiss)</author>
      <pubDate>Tue, 08 Jun 2010 14:27:44 -0700</pubDate>
      <description>&lt;p&gt;Today I had a need to get the name of a month by its number. So if I had the number &amp;#8216;6&amp;#8217; I would want to be able to get &amp;#8216;June&amp;#8217;.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;But after checking the docs for both I couldn&amp;#8217;t find anything. Google also returned nothing except the kludgey ways I already knew how to do. So I gave up and wrote this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;month = 06
date = Date.parse("2010-#{month}-01")
month_name = date.strftime("%B") # =&amp;gt; "June"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As I said it&amp;#8217;s very simple to do, but seems so unnecessarily roundabout. Parsing a string to a &lt;code&gt;Date&lt;/code&gt; object and then using the date formatter method to get the name? That doesn&amp;#8217;t smell anything like Ruby.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;So I took one more look at the &lt;a href="http://ruby-doc.org/core/classes/Date.html"&gt;docs&lt;/a&gt;, and while I was reading them it occurred to me that if the &lt;code&gt;strftime&lt;/code&gt; method can do it, Ruby must have some internal way of mapping month numbers to names. So I took a look at the actual &lt;a href="http://ruby-doc.org/core/classes/Date.src/M000608.html"&gt;source&lt;/a&gt; for &lt;code&gt;strftime&lt;/code&gt; and found the answer.&lt;/p&gt;
&lt;p&gt;Although I&amp;#8217;ve been to the doc page for the &lt;a href="http://ruby-doc.org/core/classes/Date.html"&gt;Date class&lt;/a&gt; hundreds of times, I&amp;#8217;d never really used it except to reference particular methods, so I&amp;#8217;ve always just skipped right by the constants section at the beginning. But in it there&amp;#8217;s a &lt;code&gt;MONTHNAMES&lt;/code&gt; constant, and on the first line in the section, no less.&lt;/p&gt;
&lt;p&gt;So to get the month name from a number, all you have to do is&lt;sup class="footnote" id="fnr1"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Date::MONTHNAMES[6] # =&amp;gt; "June"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ruby really &lt;em&gt;is&lt;/em&gt; made out of unicorns.&lt;/p&gt;
&lt;p class="footnote" id="fn1"&gt;&lt;a href="#fnr1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; As an added bonus, since arrays start with 0, they&amp;#8217;ve shifted the array values up one by starting the array with &lt;code&gt;nil&lt;/code&gt; at index &lt;code&gt;0&lt;/code&gt;, so you can get the actual month name of a number without having to manually subtract &lt;code&gt;1&lt;/code&gt; from that number.&lt;/p&gt;</description>
      <link>http://firebellydesign.com/blog/how-to-get-a-month-name-from-a-month-number-in-ruby</link>
      <guid>http://firebellydesign.com/blog/how-to-get-a-month-name-from-a-month-number-in-ruby</guid>
    </item>
    <item>
      <title>How to Migrate from Attachment_fu Filesystem to Paperclip S3</title>
      <author>brandon@firebellydesign.com (Brandon Weiss)</author>
      <pubDate>Tue, 02 Mar 2010 12:01:33 -0800</pubDate>
      <description>&lt;p&gt;The biggest hurdle in my quest to get our site running on &lt;a href="http://heroku.com"&gt;Heroku&lt;/a&gt; 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.&lt;/p&gt;
&lt;p&gt;Heroku is cloud-based hosting, so the solution is cloud-based storage. Any service will do, but I&amp;#8217;d recommend &lt;a href="http://aws.amazon.com/s3/"&gt;Amazon S3&lt;/a&gt;. If you aren&amp;#8217;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.&lt;/p&gt;
&lt;p&gt;Unfortunately our site wasn&amp;#8217;t using S3 yet, so the first step was to migrate all the uploaded assets to it. Luckily, if you&amp;#8217;re using a file attachment library like &lt;a href="http://github.com/thoughtbot/paperclip"&gt;Paperclip&lt;/a&gt; (which we are), that part is actually pretty easy.&lt;/p&gt;
&lt;h4&gt;Paperclip filesystem to Paperclip S3&lt;/h4&gt;
&lt;p&gt;To start, create an &lt;code&gt;s3.yml&lt;/code&gt; and put it in &lt;code&gt;config/&lt;/code&gt;. Here&amp;#8217;s what&amp;#8217;s in mine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;access_key_id: xxxxxxxxxxxxxxxxxxxx
secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
bucket: firebelly&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you like, you can also specify different accounts/buckets for &lt;code&gt;development&lt;/code&gt; and &lt;code&gt;production&lt;/code&gt; like you do for databases.&lt;/p&gt;
&lt;p&gt;Then in your model change your attachment method from something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;has_attached_file :photo&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;has_attached_file :photo,
  :storage =&amp;gt; :s3,
  :s3_credentials =&amp;gt; "#{RAILS_ROOT}/config/s3.yml",
  :path =&amp;gt; ":attachment/:id/:style.:extension"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then migrate the files themselves over to S3, and either change the structure to match your &lt;code&gt;:path&lt;/code&gt;, or change the &lt;code&gt;:path&lt;/code&gt; to match your directory structure. Be sure to set the access permissions correctly; you want Read set for all users, or the files won&amp;#8217;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.&lt;/p&gt;
&lt;h4&gt;The Plot Thickens&lt;/h4&gt;
&lt;p&gt;I thought I was done, but then I saw it, lurking in the corner: &lt;strong&gt;attachment_fu&lt;/strong&gt;. Some of our models were sadly still using attachment_fu, and while there&amp;#8217;s nothing necessarily &lt;em&gt;wrong&lt;/em&gt; with attachment_fu, Paperclip is just more modern and has become the de facto standard for file attachments. Plus, we definitely shouldn&amp;#8217;t be using two different libraries in the same app; that&amp;#8217;s just ugly. So I have to migrate all the models using attachment_fu to use Paperclip instead.&lt;/p&gt;
&lt;p&gt;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 &lt;a href="http://jystewart.net/process/2009/01/migrating-from-attachment_fu-to-paperclip/"&gt;migrating from attachment_fu to Paperclip&lt;/a&gt; written by &lt;a href="http://jystewart.net/"&gt;James Stewart&lt;/a&gt;. And just my luck, it didn&amp;#8217;t work for me. I&amp;#8217;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&amp;#8217;t figure out. So instead I hacked James&amp;#8217; script to get around the errors. Here&amp;#8217;s what I did:&lt;/p&gt;
&lt;h4&gt;Attachment_fu filesystem to Paperclip S3&lt;/h4&gt;
&lt;p&gt;First, grab a copy of the &lt;a href="http://gist.github.com/319575"&gt;Paperclip migration script&lt;/a&gt; that I forked and modified (yay, &lt;a href="http://github.com/firebelly"&gt;GitHub&lt;/a&gt;) and put it in &lt;code&gt;lib/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now make a new migration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;script/generate migration convert_project_slides&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And edit it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class ConvertProjectSlides &amp;lt; ActiveRecord::Migration
  include PaperclipMigrations&lt;/code&gt;
  
&lt;code&gt;  def self.up
    add_paperclip_fields :project_slides, :photo&lt;/code&gt;
    
&lt;code&gt;    ProjectSlide.reset_column_information&lt;/code&gt;
    
&lt;code&gt;    ProjectSlide.all.each do |project_slide|
      populate_paperclip_from_attachment_fu(project_slide, project_slide, 'photo', '/project_slides/')
    end
  end&lt;/code&gt;
  
&lt;code&gt;  def self.down
    remove_paperclip_fields :project_slides, :photo
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let me break down what&amp;#8217;s happening in this migration.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;You have to include the &lt;code&gt;paperclip_migrations.rb&lt;/code&gt; script in your migration.&lt;/li&gt;
	&lt;li&gt;Then the columns Paperclip uses need to be added to the &lt;code&gt;project_slides&lt;/code&gt; table.&lt;/li&gt;
	&lt;li&gt;The arguments that have to be passed to &lt;code&gt;populate_paperclip_from_attachment_fu&lt;/code&gt; is where I got a little confused. The first one is the model you&amp;#8217;re sending to, the second is the attachment you&amp;#8217;re sending from. In this case they&amp;#8217;re the same thing. The third one is the prefix you specified in &lt;code&gt;add_paperclip_fields&lt;/code&gt;, and the fourth is the directory where the attachment_fu files are.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The original script didn&amp;#8217;t have that fourth argument because it can be gotten &lt;em&gt;from&lt;/em&gt; attachment_fu, but inexplicably that wouldn&amp;#8217;t work for me, so I had to disable attachment_fu and specify it manually.&lt;/p&gt;
&lt;p&gt;But before you run the migration, you have to take out attachment_fu&amp;#8217;s &lt;code&gt;has_attachment&lt;/code&gt; declaration in your model. Now would also be a good time to replace it with Paperclip&amp;#8217;s declaration. So just like before, something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;has_attachment :content_type =&amp;gt; :image, 
  :storage =&amp;gt; :file_system,
  :path_prefix =&amp;gt; 'public/project_slides',
  :resize_to =&amp;gt; '345x285&amp;gt;',
  :thumbnails =&amp;gt; { :thumb =&amp;gt; '135x135!' }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Becomes something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;has_attached_file :photo,
  :styles =&amp;gt; { :thumb =&amp;gt; '135x135!' },
  :storage =&amp;gt; :s3,
  :s3_credentials =&amp;gt; "#{RAILS_ROOT}/config/s3.yml",
  :path =&amp;gt; ":attachment/:id/:style.:extension"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;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 &lt;code&gt;parent_id&lt;/code&gt; 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:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DELETE FROM project_slides WHERE parent_id IS NOT NULL&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;span class="caps"&gt;SQL&lt;/span&gt; query will delete any rows that have a value in the &lt;code&gt;parent_id&lt;/code&gt; field (which means they aren&amp;#8217;t originals).&lt;/p&gt;
&lt;p&gt;OK, all set, now you can run the migration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rake db:migrate&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assuming everything worked, you might want to drop attachment_fu&amp;#8217;s various columns from your table. The ones I had were:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;size
content_type
filename
height
width
parent_id
thumbnail&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, just upload the photos to S3 like before, set the permissions and you&amp;#8217;re done.&lt;/p&gt;</description>
      <link>http://firebellydesign.com/blog/how-to-migrate-from-attachmentfu-filesystem-to-paperclip-s3</link>
      <guid>http://firebellydesign.com/blog/how-to-migrate-from-attachmentfu-filesystem-to-paperclip-s3</guid>
    </item>
  </channel>
</rss>
