Rails Documentation Patches
May 21st, 2008
I have just commited a documentation patch to Rails which adds instructions on how to use ActiveResource::HttpMock to test your ActiveResource models. But the really cool thing is how easy it was to do.
If you ever have been frustrated because something wasnt documented clearly, or documented at all in the case of ActiveResource::HttpMock, I really encourage you to fix up that part of the rails documentation and commit a patch. The steps are simple:
- Read the docrails conventions wiki page
- Send lifo:”http://github.com/lifo” a message asking for commit access to the docrails project on GitHub. You may want to include a brief description of what you intend to fix, just so he knows your cool.
git clonethe docrails project, and write some documentation.rake rdocand review that the new documentation looks great when converted to HTML.git commitandgit push, and you are now a rails contributor!
A useful tool in this endeavor was rstakeout. It’s a script by Geoffrey Grossenbach that allows to run a command everytime a set of watched files changed. You can use it to run tests, compile HAML or SASS outside of rails, or generate the documentation when you save.
Copy this script to somewhere in your PATH and make sure its executable. Remove the .rb extension so it can be called like any other command line program. Now when working on the documentation:
cdinto the rails component you are writing documentation for.rstakeout "rake rdoc" lib/**/*This will watch all files in all directories directly underlibfor changes. This is a typical glob format and you can use as many globs as you like if you want it to watch lots of files.
Now everytime you switch over the your browser, the newly generated docs will be up to date and waiting for you to preview them after a simple refresh. Sure does save you some time.
I've seen the test driven light
May 13th, 2008
Over the past few years I have known Test Driven Development was the way to go, but my execution of that has been far from consistent.
Sometimes I think my project is too small to worry about it. But projects always get bigger than you think they will. A small bit of code with no tests isn’t really a big deal. But there is a certain project complexity threshold, where you can no longer keep the entire codebase in your head, when tests become an absolute necessity. As large bits of code become connected in an increasing number of ways, you need tests to ensure that unexpected things don’t break. And writing tests first ensure allows you to focus on just what your implementing without getting lost in the large and complicated guts of your app. The trouble is that when you start a project you don’t always know if it will reach that threshold.
Sometimes I think that I can just write tests later. After following this pattern many times, I can assure you, it is at least twice as slow as writing tests first, and your test coverage is far worse. The problem is that you have to root through your code and figure out what to test and how to test it. Coverage suffers because you are sure to miss branches of code, partly because you simply missed them, and partly because you are tired of writing tests. It just feels tedious to tread on through, writing code hours that adds no functionality to your application. It’s not fun.
Writing the tests first does a few things to make life easier:
- Write a small test, write a bit of code, is a cycle that remains fresh and fun because you are not stuck writing only tests for hours on end.
- Only writing code if you have a failing test keeps you focused. Its easy to get side tracked, fixing this and that, introducing more code changes before you are done with the current task. Focusing on smaller goals helps you code faster because there are less variables to think about all at once.
- Implement features with almost no manual testing. With a tool like
autotestits easy to add features or fix bugs without ever leaving your code editor. When all tests pass, you know you did it. One cursory manual test to confirm, is a lot faster than manually testing the features everytime you make a minor code change. - There is something very satisfying about seeing that “0 failures, 0 errors” after 45 minutes of hacking. It’s a carrot, and you just want to keep chasing it. When you get it, you just write another carrot to chase. It’s an addictive cycle.
- The ruby community will like you more. All the cool kids do it.
None of this is novel or new for those who practice this. It’s simply my own journey to the TDD religion. To be honest I am just really tired of writing tests after a large body of code has been written. It’s a painful and tedious process.
@blog_post.gsub!(/test/, "spec") |
RSpec, test/unit, test/spec, in the end I don’t think it matters. Use the test suite that is the most comfortable for you. The fact that you practice TDD is far more important than the tool you use to do it. So use the tool that makes you want to do it.
I’m not going back to my lazy old ways, I’ve finally learned my lesson.
Render Fleximage inline
May 7th, 2008
When you write your plugins the right way, Rails just works in nice ways for you. madrobby (a.k.a. Thomas Fuchs, as made famous by script.aculo.us javascript awesomeness), provided a useful tip in the Fleximage wiki on GitHub.
If you have some quick and small templates for a simple resize operation, you can do a render :inline in order to create a template on the fly for quick and easy rendering of a small template. Try this in your controller:
1 2 3 4 |
def thumb @photo = Photo.find(params[:id]) render :inline => "@photo.operate {|p| p.resize '100x100'}", :type => :flexi end |
I have never used an inline template before, but I can definitely see how that could be handy. Although, to be honest, I feel like this is very much view logic and would like to see this in a view file in all but the absolute simplest cases.
Thanks for the tip Thomas!
GitHub will support OpenID
May 1st, 2008
Thanks to some loud complaining from the community (including myself), GitHub will soon support OpenID.
Awesome.
30,000 OpenID users on 37 signals apps
April 29th, 2008
If you’re thinking about whether or not to support OpenID in your new Rails app, consider this tweet from DHH
Around 30K accounts on 37s apps are using OpenID. That’s a nice chunk!
Even if that just a few percent of the whole, 30K is a huge amount of users. And if these people are like me, OpenID support makes me much more likely to create an account somewhere. If a see a site that looks kinda cool, but I need to login to start using it, and it has a 5-10 field registration form, I usually skip it. Now if I see the same site with OpenID support, I simply enter OpenID and bypass the extended registration fields making me far more likely to signup and try it out.
If you want a chunk of that 30K, maybe you should add OpenID to your authentication as well.
While I’m on the subject, 37 signals does a cool thing if you log into their apps with OpenID. I currently have account at 3 different basecamps. I have my own basecamp, a basecamp for my primary day job, and a basecamp with another project I am helping out on. Since I login with OpenID on all three, they give me a little drop down near the top that lets me switch between basecamps. Remember that basecamp account are unique per basecamp instance. So the only way it can link my account together like that is to use my OpenID.
- Why can’t you provide this by looking for the same username? Well, since your account is specific to a basecamp instance, you can’t always have the same username in multiple basecamps.
- Why can’t you use an email, that’s globally unique right? Indeed, but I use more than 1 email address. While each email is unique, I dont have just one that means “me”. Plus in order to verify the email you have to do a messy email validation step, that noone likes doing.
- OpenID is globally unique no matter what. People usually have just one that they use. And verification is done by an identity broker rather than an email.
It all adds up to a big frickin’ win to me. This has bigger implications for me, though. What if you logged into a site, and simply by creating an account it could go out and get publicly available information about you and mash it up. Say, your favorite bands from Last.FM, the latest comments on your blog, your most recent twitter tweet. And it would be able to do all this with zero configuration because the OpenID you used on this site is the same that you used on other sites. Single Sign On is a big deal, but this is the real reason OpenID is awesome to me.
The past web was founded on the principal of anonymity, but the future of the web is grounded in absolute identity.
Fleximage is "Top Rated"
April 21st, 2008
According to AgileWebDevelopment.com Fleximage is in the first 15 “top rated” rails plugins on their site. Currently it sits at 5/5 with 71 votes. Not bad at all!
If you use it, and like it, go give it a thumbs up.
So I know you guys are out there. If you are using the plugin on a production site, go ahead and add yourself to the Who uses Fleximage Wiki page over on Github. I would love to see what you creative have done with dynamic images.
Fleximage now form redisplay safe
April 15th, 2008
There was a minor annoyance with all version of Fleximage up to this point. If you upload an image to a model, and validation fails for whatever reason, then you would have to find the image on your disk again, re-upload the image again, before you resubmit the form. Wouldn’t it be nice of the file stayed uploaded, even if the record isnt ready to be saved yet? How about getting a preview of the uploaded image too?
It’s all possible with the latest version of Fleximage up on GitHub. Checkout this GitHub wiki page for details.
Settings Plugin update
April 12th, 2008
Since GitHub makes open source so easy I opened up my old Settings plugin after almost a year and put it up with a few improvements.
Most importantly, I got the tests working. I also created a less ugly way of defining defaults:
1 2 3 4 5 6 |
Settings.defaults[:foo] = 'bar' # or Settings.defaults = { :foo => 'bar', :baz => 'faz', }.with_indifferent_access |
GitHub: Open source is now easier than Closed source
April 11th, 2008
I usually don’t blog about stuff that everyone else is obviously blogging about already. But I am making an exception, just this once, because I am excited about GitHub.
GitHub is a social source control platform based on Git. Git is a whole different animal than SVN. Git has no concept of source and checked out copy. You can commit locally, you can easily branch and merge, you can push some branches to some central repos, and keep other to yourself for now, its amazingly dynamic. But I’m not here to talk about Git so much.
The first part that makes GitHub cool is the social thing. It’s been really hard for me to get into social networks. I try every once and a while and find it hard to convince my peers to join me on said network. I can upload a widget, or have a friends list, but I never seem to find any functionality that keeps me using the network for any length of time. GitHub is finally a social network I can get into. You don’t have “friends”, you have contibutors, watchers and forkers. You can add people to your project as contributors, people can simply keep an eye on your project by watching it, or they can fork your code to make their own modifications in their own sandbox. It’s completely addicting to see how many “Watchers” I have today. As of this writing the Fleximage watcher page lists 9 watchers. Not bad for less than 1 week in the wild.
Now, lets say someone wants to add some useful functionality to Fleximage. They can fork my code, without my permission, and work on their useful feature. They then let me know saying “I did some cool stuff, check it out”. I can clone their working repo, test it out, and integrate the diff with my code with just a few commands. Even if someone forks my code in order to overlay a monkey watermark on every image, that’s still fine. They can keep their forked little sandbox for themselves or whoever else wants to use it and I never have to pull in their changes at all.
The second part that is awesome is what this does for open source. The pricing model really encourages open source. Open source hosting is free. Private repositories cost money. Let that sink in a minute. This means that its easier and cheaper to release your project open source than not to. Previously, to open source a project you needed server side repository hosting, need a website for your project, in order to get those free you needed the convoluted rubyforge interface or ad laden source forge. This made it more time consuming and costly than a private codebase. So the “default” mode for most apps was private, because it was easier.
What GitHub did, was to make open source easier and cheaper than closed source. So going forward my apps will be, by default, open source. Thats a big deal. Now the little nuggets that I write every now and again will be opensourced on GitHub. Some of them may turn out to be nothing. But other may get forked by someone far smarter than me, enhanced, and eventually turned into something totally cool. Such scenarios never would be possible if there wasn’t an easy and free open source hosting platform like GitHub.
GitHub, you guys rock. The worldwide open source community has been greatly enhanced by the presence of GitHub. Give it some time and I think GitHub will be the defacto open source standard.
Ruby Experts
April 6th, 2008
Hey look, I’m a Ruby expert
Not sure how I stack up with people that wrote Ruby books… Had I realized that I was going to be quoted in such a manner, perhaps I would have answered with slightly more verbosity. Live and learn.
Fleximage v2, now with more awesome
April 5th, 2008
You ever make something, and then look back a few years later and say “What the hell was I thinking”? This happened to me recently. Fleximage has been quite a useful plugin for me, but under the hood it was a mess; the API was cumbersome, and mixing in all the image transformations as direct model methods was code smell.
This release represents the 3rd complete rewrite of this code base. The first effort was SuperImage. It worked, but it happened almost entirely in the controller and made more interesting effects harder. The first Fleximage was next introducing more tranformations and .flexi views and a good effort to making it more MVC friendly.
Get Fleximage v2 here
So I now present, Fleximage v2. The output is very similar, but the API and internals are completely different. Here’s some highlights.
- Creation date based master image storage to prevent OS imposed directory limits. i.e. /path/to/images/2008/02/06/999.jpg
- Rails 2 formatted resource route friendly
- Magic columns to capture filename and image size
- Image transformation methods are not injected into your model or controller at all.
- Image operations now happen via Operator class that refactor each transformation into their own encapsulated class.
- Easily output JPG, PNG, or GIF based on request format.
- Simple acts_as_* style model activation rather than using a cumbersome inheritance method
- Side by side file upload or URL fields for easy uploading.
- Uploading will only ever replace you image file if the uploaded file actually has content, removing the need for “if file.size > 0” nonsense in your controller.
- Rake tasks to convert from master image directory styles, as well as master image formats (jpg => png for instance)
And it’s all hosted on GitHib. It’s new, it’s awesome, and has extensive documentation in the attached Wiki.
Lastly, if you are using Fleximage in an existing production site, please add it on the WhoUsesFleximage page. I know you’re out there.
Heroku and the Hillcrest Development Watch
March 29th, 2008
A friend asked me to donate a tiny google maps application to a non-profit cause. The Hillcrest Development Watch monitor housing and construction in their area and they wanted an easier way to do it than emailing a spreadsheet around. Now, being a Rails programmer, of course I wanted to deal with this in Rails. Sadly Rails is a pain to host right?
Wrong. Enter Heroku. Their fantastic setup is free (for now). They create a git repository for your app when you create your app. Then you simply suck down that git, commit to it and push it back. Their server software automatically updates your working code and reboots your app to the latest code, simply by pushing your commits to the server. It is the least painful rails deployment process I have ever used. In fact, I would go so far as to call it pleasurable, which is a big deal to say about rails deployment.
Check out Hillcrest Development Watch
The site itself is a simple single resource web app. It tracks properties, their addresses and development states. For a supre small app like this, Heroku even provides access to its user login system. It lets you use the user logged into heroku.com as a user in your app. So if your needs are simple, you can have a user authentication system, and have your app not care about registration, authentication, or user management. This app simply show some admin function if the user is authorized to edit this heroku app. This wouldn’t stand up to the needs of anything more complex, but it saved a huge bundle of time for this project.
In case this lengthy prose didn’t convey my point:
Heroku is Aweome!
Learning Objective C
March 8th, 2008
With the release of the iPhone SDK, it’s clear that I need to learn some Objective C. I have been meaning to pick it up for a while now, if only to write Mac OS X Desktop Apps. But coming from Ruby, and not knowing C, its a little weird. I have a brain dump of initial thoughts as I trudge through my learning process that I will document here.
First of all, memory management? Ruby has way spoiled me here. Having to manually allocate and deallocate memory manually seems like a huge pain the ass. But on the other hand, maybe that is one reason that Rails apps take need 50MB of RAM just to be present.
The bracket method invocation syntax is pretty weird to me. As is the method declaration syntax. I’m getting used to it, I am starting to see why it’s done that way. But its still ugly.
1 2 3 4 5 |
// method declaration - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // method invocation [myObject touchesBegan:someTouches withEvent:someEvent] |
The “every argument is named” thing, is actually pretty nice. But the syntax to hook all that up, and strongly type every argument, is pretty ugly.
Lastly, for now, the language just seems needlessly verbose. For example, to create a new Photo:
photo1 = [[Photo alloc] init]; |
I much prefer ruby’s Photo.new. Or to get objects out of an NSArray object you actually have to do something like:
[myArray objectAtIndex:123] |
Learning a new language is a great mind expanding exercise. But I hope to, one day, learn a language that didn’t make me wish I was using ruby instead.
FleursFrance.com
February 21st, 2008
I have been developing a little site for the florist of my recent wedding. It’s a simple custom designed Rails CMS. Its got some page content management, a cool gallery manager, and of course, FlexImage is used to resize images and stamp them with a custom copyright.
The main problem with the images is that some were taken by the florist herself, but other are taken by professional photographers, and proper credit needed to be given. So I provided a simple text field that will write anything to the bottom left of an image allowing custom copyright on a per photo basis. And permanently stamping it on the image meaning it can’t be stolen, at least without a nasty cropping, but there is only so much you can do against that.
It’s been a fun little project.
Starting to learn Actionscript 3.0
December 14th, 2007
Yep, due to occupational necessity, I am starting to learn Actionscript 3.0 and Flash. So what do I make, why a particle system of course!
This SWF has a particle system class capable of 3D sprays of colored balls, including completely configurable 3D gravity, size, speed, emitter angle, alpha, color and a few others I am sure I forgot.
Actionscript 3.0 is no ruby, but I am still enjoying myself.
Although since I can’t override operators like I can in ruby, in order to add 2 vectors together (or mltiply/divide/subtract) my Vector class has to do this:
var vector3:Vector = vector1.add(vector2); |
Instead of the hot and sexy ruby possibility of:
vector3 = vector1 + vector2 |
At least I can use Textmate to write the *.as files.