Railscasts
Anyone looking to learn more about Rails development could do a lot worse than watching the excellent video podcasts available at http://www.railscasts.com. All archives of the show are available, and I would strongly encourage you to download and watch all of them. They are very quick and to the point but not at the expense of quality. There is a lot of great material packed into a five minute vidcast. Is that even a word? :)
GMail Update
Are there others whose gmail accounts have been updated to support IMAP? At this point, my two Google Apps domain accounts have had this featured rolled out, but the gmail account has not. I’m wondering what the process is and how much longer I have to wait for IMAP. Hopefully, Im not coming across as a whiner. :)
Update: Less than an hour after this post, IMAP is now enabled on my gmail account. :D
It’s midnight, Cinderella
The ball’s over. Congratulations, Colorado Rockies. It’s been a good run. As expected though, the Boston Red Sox simply outclassed you in the World Series.
LogRotate on Joyent Accelerators
Recently, I finished rolling out a new client site on a Joyent Accelerator. The site uses Rails and one thing thats both positive and negative is the amount of information that gets logged. Granted, when RAILS_ENV is production, the amount of data that gets logged is much less than when RAILS_ENV is development. However, even when set to production, there is a significant amount of data which gets logged. The good part of this is that when something goes wrong, it’s very easy to pinpoint the problem. The drawback is that these log files can chew up disk space when not managed properly. Enter the logrotate command…
From the man pages:
logrotate is designed to ease administration of systems that generate large numbers of log files. It allows automatic rotation, compression, removal, and mailing of log files. Each log file may be handled daily, weekly, monthly, or when it grows too large.
The easiest way to get logrotate set up on your Joyent Accelerator is to create a logrotate.conf file in your home folder. This config file would look like this:
superbia:~ mattb$ cat logrotate.conf
/path/to/rails/site/log/*.log {
daily
missingok
olddir old
rotate 28
copytruncate
compress
compresscmd /usr/bin/gzip
}
The important components of this config file are:
- daily: This line tells logrotate that we want to rotate files on a daily basis
- copytruncate: This command tells logrotate that after copying the files, the original log should be truncated. This avoids us having to kill the Mongrels after copying the log files.
- compress: In order to actually save some space with the logs, we want to compress the log files.
- compresscmd: This is the command that we use to compress the logs. With a Joyent Accelerator, it is necessary to specify /usr/bin/gzip, otherwise you will encounter some strange errors.
Once the conf file is ready, we can test to make sure that everything is working. Execute this command (you can pass -v if you would like verbose information).
superbia:~ mattb$ logrotate -f -s ~/var/log/logrotate.status ~/logrotate.conf
Once the command has completed, you should be able to go into your rails folder and see that your logs have been cleaned up.
The last step will be adding this to your crontab so that it executes on a daily basis.
0 0 * * * logrotate -s /path/to/logrotate.status /path/to/logrotate.conf
Thank you to the fine folks at Joyent for helping me work through getting this running. If you’re looking for some great hosting, you wont do much better than those guys.
Interesting Trivia
Did you know that you can burn 150 calories by banging your head against the wall for an hour?
I cant remember exactly where or when I heard this, but at times it seems strangely appropriate.
Uploading files to a database using Rails
Not long ago, I needed a way for users to upload files and store them in a database. The platform for the application was Ruby on Rails, and I wanted to share my experience here.
The first thing we want to do is generate the table for the attachments:
superbia:~/Projects/Attachments mattb$ script/generate model Attachment
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/attachment.rb
create test/unit/attachment_test.rb
create test/fixtures/attachments.yml
create db/migrate
create db/migrate/001_create_attachments.rb
This line does a number of things for us, including generating the model class, an associated unit test and fixture, as well as a migration class. The next thing we want to do is fill out the migration class so that we can create the database table. In our case, we will need a filename, content_type and attachment column.
class CreateAttachments < ActiveRecord::Migration def self.up create_table :attachments do |t| t.column :filename, :string t.column :content_type, :string t.column :data, :binary end end def self.down drop_table :attachments end end
Let’s now run this migration to create the table in our database:
superbia:~/Projects/Attachments mattb$ rake db:migrate (in /Users/mattb/Projects/Attachments) == CreateAttachments: migrating =============================================== -- create_table(:attachments) -> 0.0218s == CreateAttachments: migrated (0.0220s) ======================================
The next thing that we’ll need to do is to create a controller to process the submitted attachment.
superbia:~/Projects/Attachments mattb$ script/generate controller Attachments show create
exists app/controllers/
exists app/helpers/
create app/views/attachments
exists test/functional/
create app/controllers/attachments_controller.rb
create test/functional/attachments_controller_test.rb
create app/helpers/attachments_helper.rb
create app/views/attachments/show.rhtml
create app/views/attachments/create.rhtml
class AttachmentsController < ApplicationController def show @attachment = Attachment.find(params[:id]) send_data @attachment.data, :filename => @attachment.filename, :type => @attachment.content_type end def create return if params[:attachment].blank? @attachment = Attachment.new @attachment.uploaded_file = params[:attachment] if @attachment.save flash[:notice] = "Thank you for your submission..." redirect_to :action => "index" else flash[:error] = "There was a problem submitting your attachment." render :action => "new" end end end
The relevant snippet of the view code that utilizes this is in new.rhtml:
<% form_tag 'create', :multipart => true do %> <%= file_field_tag 'attachment' %> <%= submit_tag "Send Attachment" %> <% end %>
The important parts of the view are the multipart declaration; without this, your file will not be submitted. Also, we take advantage of the file_field_tag helper method to output the file browser.
If we run the application now and try to upload a file, we will be presented with an error, because the uploaded_file method does not exist on the Attachment model. Let’s complete our model.
class Attachment < ActiveRecord::Base def uploaded_file=(incoming_file) self.filename = incoming_file.original_filename self.content_type = incoming_file.content_type self.data = incoming_file.read end def filename=(new_filename) write_attribute("filename", sanitize_filename(new_filename)) end private def sanitize_filename(filename) #get only the filename, not the whole path (from IE) just_filename = File.basename(filename) #replace all non-alphanumeric, underscore or periods with underscores just_filename.gsub(/[^\w\.\-]/, '_') end end
The meat of this model is the uploaded_file method, which the controller calls, passing the uploaded file. This method is responsible for mapping the incoming file to the attributes expected by our database schema. Additionally, we’re sanitizing the filename, so that we are not only getting just the filename, but we’re also cleaning up any extra characters and replacing them with underscores.
I’ll leave it as an exercise for the reader to associate the attachment with a given user. The “magic” of Rails makes this really straightforward.
Debugging XSLT with VS2005
I am probably the last guy to know about this, but just in case…
Apparently, you’re able to debug XSLT with Visual Studio 2005 by setting an input XML file on the properties of the XSLT, setting some breakpoints as you normally would and then clicking Debug XSLT on the XML menu.
You get all the normal debug windows, the ability to step into, over and out of templates. In addition, you get to see the output as it develops in another window.
Thanks for the tip, Adrian… I suppose I can now get rid of Stylus Studio. :)
Some Rails Misconceptions
Rob Conery seemed to stir up quite a firestorm in his post earlier today about imploding rails. I enjoy reading Rob’s posts and really appreciate his contribution to the community, but on this one, I have to disagree with him.
Rob Conery rails DHH (no pun intended) for using the term “fuck you” in a presentation. Rob stated that DHH used the term when explaining to his audience who he is writing rails for. However, as has been pointed out previously, Rob has clearly misstated the use of the word. The presentation centered on people saying that Rails is not ready for the enterprise and this is what he tells them.
I wonder though who has the bigger history of saying “fuck you” to the community. Did Microsoft say “fuck you” to the community by not leveraging the community’s work into NUnit and creating their own version? What about MSBuild vs NAnt? How about TFS vs SVN? How about System.Web.MVC instead of MonoRail? I wonder if Jamie Cansdale feels like Microsoft gave him a big “fuck you” by suing him for his TestDriven.NET addin to Visual Studio.
Rob also states that Rails team is a now vendor and not “radical mavericks”. The Rails team is anything but a vendor. They have built a web framework around things that they find value in. They have chosen to share that framework with the world. If you like and agree with their perspectives on aesthetics, then use it. If you don’t like it, maybe Rails isnt for you.
There are plenty of other frameworks to choose from. This is not about a software behemoth trying to control every aspect of your development environment. As I said in an earlier post, Rails is all about your choice to use their framework and of consistency in values and beliefs of what makes a good software project. Rails will not sacrifice the aesthetics of the code to appeal to a broader audience.
I’ll close with this: if Microsoft has gotten it figured out, as Rob claims, why are so many people leaving Microsoft development?
RSpec Top to Bottom
I have to thank Tim Haines for turning me on to RSpec not long ago via his LinkBuddy facebook application. I’ve been trying to suck in as much information as possible about this intriguing tool. Imagine being able to describe your stories *AND* their corresponding acceptance criteria in code, and then being able to execute those tests to demonstrate that functionality is complete.
Pat Maddox created a screencast that talks about this tool, as well as Story Runner. The screencast is rather lengthy (35 minutes, 102megs) but it is worth its weight in gold. Whether you are looking to learn more about this tool, or whether you are simply looking to gain more information into what constitutes a complete story, this screencast is absolutely recommended.
The tool is specific to Ruby, however the concepts can be applied broadly to any sort of agile development. Structuring an effective story is probably the biggest hurdle to successful agile implementation.
Essential Software for OSX
Last week, I ended up getting an absolutely gorgeous 17in MacBook Pro. As is typical from Apple, the out of box and setup process was absolutely perfect. The aesthetics of this computer are absolutely stunning. I spent the extra few dollars to get the 1920×1200 display, which was so worth it. Within 5 minutes, I had the machine booted up and connected to the internet.
Which leads to the point of this post… what software did I install on this new machine? What do I find to be essential software for OSX?
QuickSilver: QuickSilver is the single best tool in existence now. Period. QuickSilver is one of those tools that is almost impossible to accurately describe, but once you grok it, it becomes indispensable. This tool was the primary reason I bought my first Mac last year.
TextMate: TextMate is arguably the best text editor available on any platform. It has become the defacto standard for Ruby on Rails development. By the way, there’s also a blogging module for TextMate which Im using to post this entry.
Parallels Desktop: Sometimes, you still have to use Windows.
1Passwd: This is the best password manager I have yet to find for any OS. The best part of this tool is how it integrates with the keychain to provide access to your passwords by any supported browser (Safari and Firefox are supported, of course).
iTerm: Terminal.app is greatly lacking compared to iTerm. With support for tabs, this tool is a great way to run multiple terminals at once without cluttering up your desktop with windows.
Lastly, of course, I installed Ruby, Rails, Subversion, Mongrel and MySQL using the tutorial over at HiveLogic.


