<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Brain Matters &#187; gettext</title>
	<atom:link href="http://blog.agoragames.com/tag/gettext/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.agoragames.com</link>
	<description></description>
	<lastBuildDate>Mon, 16 Aug 2010 19:36:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Porting Legacy Applications to Modern Systems</title>
		<link>http://blog.agoragames.com/2009/01/12/porting-legacy-applications-to-modern-systems/</link>
		<comments>http://blog.agoragames.com/2009/01/12/porting-legacy-applications-to-modern-systems/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 17:58:36 +0000</pubDate>
		<dc:creator>Jason LaPorte</dc:creator>
				<category><![CDATA[Bending Rails]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[attachment_fu]]></category>
		<category><![CDATA[file_column]]></category>
		<category><![CDATA[gettext]]></category>
		<category><![CDATA[legacy]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.agoragames.com/?p=125</guid>
		<description><![CDATA[(Or, an adventure in pain!)
Let me preface this little article by saying I did not write the app I am now porting to our new network. I know noting about its specific intricacies, and furthermore, I know nothing specifically about gettext, file_column, or attachment_fu. So, I dove into this project with a sort of wanton [...]]]></description>
			<content:encoded><![CDATA[<p><em>(Or, an adventure in pain!)</em></p>
<p>Let me preface this little article by saying I did <strong>not</strong> write the app I am now porting to our new network. I know noting about its specific intricacies, and furthermore, I know nothing specifically about gettext, file_column, or attachment_fu. So, I dove into this project with a sort of wanton abandon that is fairly characteristic of much of the work I do. Any obviously stupid mistakes below thus really happened.</p>
<p>Let me also preface this with the fact that this Rails app is old. Version 1.2.3 old. So, as always, YMMV.</p>
<p>Finally, I really wish attachment_fu had proper documentation.</p>
<p><span id="more-125"></span></p>
<h2>Installing GetText 1.10.0</h2>
<p>We don&#8217;t really like GetText around here, but, at the time, it was the only option. Getting it running off of a local copy (so I wouldn&#8217;t have to pollute other projects with it) was less difficult than I expected. Go to your vendor/gems directory and issue:</p>
<pre>gem unpack gettext</pre>
<p>This assumes you have gettext 1.10.0 installed locally. I think adding a VERSION=1.10.0 will handle it if you have multiple gettext versions laying around. After that, I merely needed to add the following to config/environment.rb to make sure the gem loaded:</p>
<pre>GETTEXT_GEM_DIR = "#{File.expand_path(RAILS_ROOT)}/vendor/gems/gettext-1.10.0"
$LOAD_PATH.reject { |path| path =~ /gettext/ }
$LOAD_PATH &lt;&lt; GETTEXT_GEM_DIR
$LOAD_PATH &lt;&lt; File.join(GETTEXT_GEM_DIR, 'lib')
$LOAD_PATH &lt;&lt; File.join(GETTEXT_GEM_DIR, 'ext', 'gettext')
require File.join(GETTEXT_GEM_DIR, 'lib', 'gettext.rb')</pre>
<p>Ta-da!</p>
<h2>Replacing File_Column With Attachment_Fu</h2>
<p>After doing the above and booting up a test server, I get the following fun error:</p>
<pre>no such file to load -- RMagick</pre>
<p>There is no way I am ever installing RMagick onto our nice, new, beautiful infrastructure. I want things done right, here. I also don&#8217;t want to have to be paranoid about memory leaks, especially for legacy applications. So, we have to get rid of it.</p>
<p>This problem is caused by our use of file_column, an old-but-effective way of easily adding file uploading support into a Rails app. The modern <em>de facto</em> standard for this seems to be attachment_fu, which uses the much-better-designed ImageScience instead of RMagick.</p>
<p>So, let&#8217;s gut this fish.</p>
<h3>Remove File_Column.</h3>
<pre>$ svn rm vendor/plugins/file_column</pre>
<h3>Install ImageScience.</h3>
<pre>$ sudo apt-get -y install libfreeimage3 libfreeimage-dev
$ sudo gem install image_science</pre>
<h3>Install Attachment_Fu.</h3>
<pre>$ script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/</pre>
<p>After installing attachment_fu, I powered back up script/server to check the next fun error:</p>
<pre>undefined method `file_column' for Clan:Class</pre>
<p>This is expected: file_column is gone, so the app can&#8217;t possibly know what a file_column is. Now, we have to get into the nitty-gritty of tweaking the app.</p>
<h3>Adapting the Application to Attachment_Fu.</h3>
<p>Let&#8217;s start in app/models/clan.rb, to which I was directed by the aforementioned error:</p>
<pre>$ grep file_column app/models/clan.rb</pre>
<p>No output. The words file_column don&#8217;t appear in that class. Not what I expected.</p>
<p>In the time-honored tradition of killing a cockroach with a shotgun, I then turned my sights on the entire app directory:</p>
<pre>$ grep -R file_column app</pre>
<p>The only results that turn up happen to be in app/views, leaving me perplexed. A quick conversation with the project lead informs me that this application uses &#8220;skeletons&#8221;, or appable_plugins, which was an absolutely horrible idea that we thankfully no longer use. In essence, it allows you to wrap pieces of functionality into a self-contained plugin, which is duck-punched onto your application when it starts. It is great from a code-reuse perspective, but horrible from a KISS and maintenance standpoint, which is why we no longer use it.</p>
<p>Except that every now and again, it comes back to bite you in the ass when you least expect it.</p>
<p>Anyway, checking the skeletons quickly turns up what I am looking for:</p>
<pre>$ grep -R file_column vendor/skeletons/clan_skeleton
vendor/skeletons/clan_skeleton/app/models/clan.rb:  file_column :avatar_image, :magick =&gt; { :size =&gt; "64x64!"}</pre>
<p>So, there is where I have to make the first incision. I changed it as follows:</p>
<pre># file_column :avatar_image, :magick =&gt; { :size =&gt; "64x64!"}
# validates_filesize_of :avatar_image, :in =&gt; 0..40.kilobytes

has_attachment :content_type =&gt; :image,
               :storage =&gt; :file_system,
               :max_size =&gt; 40.kilobytes,
               :resize_to =&gt; '64x64!'

validates_as_attachment</pre>
<p>Time to restart the server and try again. (I don&#8217;t honestly expect it to work: there are (at least!) a lot of views that use file_column methods. It is easiest to just hack at them one at a time until everything works, though!)</p>
<p>I spent the next couple hours digging through the innards of attachment_fu, only to discover that I had written :filesystem, above, instead of :file_system (note the underscore). Make sure you spell things correctly, people, or you&#8217;ll be in for a world of self-induced hurt. (The above snippet shows things the correct way, so you, my beloved internet, won&#8217;t inadvertently copy-and-paste yourself into hell.)</p>
<p>Once I had properly spelled everything, though, I met with success: the front page of the site loaded! Clicking on just about anything yielded a failure, as anticipated:</p>
<pre>undefined method `url_for_file_column' for #&lt;#&lt;Class:0x7f7d7f3006c0&gt;:0x7f7d7f300670&gt;</pre>
<p>The views didn&#8217;t work, but the fix wasn&#8217;t horrible. Generally speaking, I simply searched and replaced the following:</p>
<pre>url_for_file_column(X, 'avatar_image')</pre>
<p>with:</p>
<pre>X.public_filename</pre>
<p>Also, along with this, I modified the clan table&#8217;s SQL schema to accomodate attachment_fu:</p>
<pre>ALTER TABLE clans CHANGE avatar_image filename VARCHAR(255) DEFAULT NULL;
ALTER TABLE clans ADD (content_type VARCHAR(255) DEFAULT NULL,
                       size INT DEFAULT NULL,
                       width INT DEFAULT NULL,
                       height INT DEFAULT NULL);</pre>
<p>Thankfully, this was pretty easy to do, since the clans table was very small for this particular title. If it were larger, I would create a separate table and do a</p>
<pre>SELECT * FROM clans INSERT INTO clans_temp</pre>
<p>sort of thing. (Yes, I know that it is very evil to hack the SQL directly instead of using migrations. This app is sufficiently old that I cannot guarantee that its migrations even work; I&#8217;m already spending a lot of time trying to port this app, I don&#8217;t want to spend much more trying to make it perfect. If it weren&#8217;t a legacy application, however, I would do things a bit more cleanly.)</p>
<p>At this point, virtually everything on the site worked. Avatars (once moved to the proper new directories) showed up just fine. The only remaining error came from trying to upload a new avatar image. Solving this essentially boiled down to a complex series of hacks to blend attachment_fu into the remainder of the existing codebase; none of which were particularly complex or interesting (generally involving changing the names a form parameters from the previous :avatar_image to the new :uploaded_data, like this:)</p>
<pre>&lt;%#= file_column_field 'clan', 'avatar_image' %&gt;
&lt;%= file_field_tag :uploaded_data %&gt;</pre>
<p>Doing all this left me with one final application error, received when actually performing the file upload:</p>
<pre>Content type is not included in the list
content type can't be blank</pre>
<p>Validations are complaining. After tinkering with attachment_fu&#8217;s code for a while, I discover that there is a method that attachment_fu adds to your ActiveRecords (uploaded_data=), which sets content_type and other miscellaneous variables. And, clearly, this wasn&#8217;t getting called.</p>
<p>Turns out I was getting bitten by multipart forms. By tossing a quick</p>
<pre>puts params.inspect</pre>
<p>into the code, I quickly saw where my problem lay. Notice the following bit from our clans controller&#8217;s update method:</p>
<pre>@clan.update_attributes(params[:clan])</pre>
<p>Unfortunately for me, the uploaded data is in params[:uploaded_data], and not in params[:clan][:uploaded_data]. While there&#8217;s a cleaner fix, the following hack suits our purposes fine and allows me to finish up this 20-hour hackfest:</p>
<pre>params[:clan][:uploaded_data] = params[:uploaded_data]</pre>
<p>So, after all of this code mangling, we finally had our app ready to move to a new, lighter-weight infrastructure, ultimately saving us money. A very frustrating few days, but they will pay for themselves. All that remains is integrating into a new infrastructure, and switching over the DNS.</p>




	<a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F01%2F12%2Fporting-legacy-applications-to-modern-systems%2F&amp;title=Porting%20Legacy%20Applications%20to%20Modern%20Systems" title="Reddit"><img src="http://blog.agoragames.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F01%2F12%2Fporting-legacy-applications-to-modern-systems%2F&amp;title=Porting%20Legacy%20Applications%20to%20Modern%20Systems&amp;bodytext=%28Or%2C%20an%20adventure%20in%20pain%21%29%0D%0A%0D%0ALet%20me%20preface%20this%20little%20article%20by%20saying%20I%20did%20not%20write%20the%20app%20I%20am%20now%20porting%20to%20our%20new%20network.%20I%20know%20noting%20about%20its%20specific%20intricacies%2C%20and%20furthermore%2C%20I%20know%20nothing%20specifically%20about%20gettext%2C%20file_co" title="Digg"><img src="http://blog.agoragames.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F01%2F12%2Fporting-legacy-applications-to-modern-systems%2F&amp;title=Porting%20Legacy%20Applications%20to%20Modern%20Systems&amp;notes=%28Or%2C%20an%20adventure%20in%20pain%21%29%0D%0A%0D%0ALet%20me%20preface%20this%20little%20article%20by%20saying%20I%20did%20not%20write%20the%20app%20I%20am%20now%20porting%20to%20our%20new%20network.%20I%20know%20noting%20about%20its%20specific%20intricacies%2C%20and%20furthermore%2C%20I%20know%20nothing%20specifically%20about%20gettext%2C%20file_co" title="del.icio.us"><img src="http://blog.agoragames.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.agoragames.com%2F2009%2F01%2F12%2Fporting-legacy-applications-to-modern-systems%2F&amp;t=Porting%20Legacy%20Applications%20to%20Modern%20Systems" title="Facebook"><img src="http://blog.agoragames.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://www.tumblr.com/share?v=3&amp;u=http%3A%2F%2Fblog.agoragames.com%2F2009%2F01%2F12%2Fporting-legacy-applications-to-modern-systems%2F&amp;t=Porting%20Legacy%20Applications%20to%20Modern%20Systems&amp;s=%28Or%2C%20an%20adventure%20in%20pain%21%29%0D%0A%0D%0ALet%20me%20preface%20this%20little%20article%20by%20saying%20I%20did%20not%20write%20the%20app%20I%20am%20now%20porting%20to%20our%20new%20network.%20I%20know%20noting%20about%20its%20specific%20intricacies%2C%20and%20furthermore%2C%20I%20know%20nothing%20specifically%20about%20gettext%2C%20file_co" title="Tumblr"><img src="http://blog.agoragames.com/wp-content/plugins/sociable/images/tumblr.png" title="Tumblr" alt="Tumblr" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://twitter.com/home?status=Porting%20Legacy%20Applications%20to%20Modern%20Systems%20-%20http%3A%2F%2Fblog.agoragames.com%2F2009%2F01%2F12%2Fporting-legacy-applications-to-modern-systems%2F" title="Twitter"><img src="http://blog.agoragames.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://blog.agoragames.com/2009/01/12/porting-legacy-applications-to-modern-systems/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->