Skip to main content


Showing posts from July, 2009

Python: Planet Python Update

If you read my blog through Planet Python, you'll now only see my blog posts which have been explicitly tagged with Python. If you want to see all the rest of the things I blog about, such as JavaScript, Rails, Oz, Haskell, Erlang, Linux, etc., you'll need to subscribe directly to my blog.

Sorry for the inconvenience. I had to make this change because a lot of Python programmers didn't like seeing Rails-related posts showing up on Planet Python.

Thanks for reading!

Rails: Configuring Admins, Checkboxes, and attributes= Vulnerabilites

I'm using acl_system2 together with authlogic to provide ACLs for my Rails app.

I wanted to provide a list of checkboxes so that an admin can configure the list of roles assigned to a user. Since Rails really prefers to work with one model per form, and the list roles are separate from the user record itself, it took me a while to figure out how to do this. Thankfully, I found this post which showed me how to do it. The code looks like:<% restrict_to "admin" do %>
<%= form.label :role_ids, "Roles" %>
<% Role.all.sort.each do |role| %>
<% field_id = "role_#{}" %>
<br />
<%= check_box_tag "user[role_ids][]",, @user.role_ids.include?(, {:id => field_id} %>
<%= label_tag field_id, h(role.title) %>
<% end %>
<% end %>Without any changes to my controller, it just worked. However, that worried me.

I suddenly realized …

Rails: Forcing a Controller to have a Comment

I'm using acl_system2 for authorization. As a general rule, I think apps should deny access to everything, and then open up permissions where appropriate. However, acl_system2 makes it hard to restrict permissions in ApplicationController and open them up in each subclass.

That means I have to remember to control access in each controller. acl_system2 will allow access unless you tell it not to. That could lead to accidents. Hence, I started with the following in ApplicationController:# === Access controls
# Each controller is responsible for enforcing access controls properly. It
# should either have some variation of::
# before_filter :require_user
# access_control :DEFAULT => 'admin'
# Or at the very least::
# # No access control is required:
# # before_filter :require_user
# # access_control :DEFAULT => 'admin'
# See for more details.Of course, that's just a comment which no one will ever r…

Rails: Tests vs. Docs

I've been accused before of relying too heavily on documentation and not heavily enough on tests. I wrote the following in my README_FOR_APP:==== Unnecessary Files

You probably should not need to create files in any of these directories, and
you should not commit any autogenerated files to these directories. Each of
these directories has a README explaining why and what we're using instead::

* app/views/layouts
* test/fixtures
* test/functional
* test/integration
* test/unit
* test/unit/helpers(I'm using RSpec, factory_girl, etc., so a lot of those directories are unnecessary. I only have one layout.)

I thought to myself, how would a TDD person solve this problem with tests instead of documentation? Hence, I created spec/hieararchy_spec.rb:require File.expand_path(File.dirname(__FILE__) + '/spec_helper')

context "the file hierarchy in this Rails app" do
directories = {
"app/views/layouts" => ["main.html.erb"],

Rails: authlogic and acl_system2 under Rails 2.3.2

Updated: Documented my migration.

I got authlogic and acl_system2 to work together under Rails 2.3.2. authlogic provides authentication. acl_system2 provide authorization, i.e. ACLs. authlogic is very up-to-date, but acl_system2 is a bit dated. That's okay, though, because it's not the sort of thing that should need to change much.

Let me cover some of the stumbling blocks I encountered after I followed the authlogic tutorial and the acl_system2 documentation.

acl_system2 is not available as a gem. Hence, you need to install it via:script/plugin install git:// you followed the authlogic tutorial, you'll end up with the ApplicationController#current_user method being private. To work with acl_system2, it should instead be protected. Otherwise, you'll end up with this:You have a nil object when you didn't expect it!
The error occurred while evaluating nil.roles (NoMethodError)

This Isn't a Pure Python Blog

I've been getting some flack about my Ruby-related posts showing up on Planet Python. On the one hand, I have never intended this to be a pure-Python blog. On the other hand, since most of my readers come from Planet Python, I surely don't want to upset them.

I work at two startups. One uses Python with Pylons. The other uses Ruby on Rails. This puts me squarely in both camps. In general, I try to code in and blog about as many technologies as I have time for. Hence, you'll often see posts about weirder things like Haskell, Erlang, Oz, etc.

I can understand how it would be frustrating for some people to read about Rails on Planet Python. In fact, I got kicked off of Planet Haskell because I spent too much time blogging about Python! Now, I could probably wax philosophic about the increasingly insular nature of programmers in our industry, but given how many times I've made fun of Java, it probably wouldn't do me any good ;)

If you have any advice, I'd lov…

Rails: RSpec, Cucumber, Authlogic, and factory_girl

After a day of work and a week of reading The RSpec Book, I got RSpec, Cucumber, Authlogic, and factory_girl to play nicely with each other. I can now test user registration, logging in, and logging out.

I can't possibly cover everything from scratch, but I'll cover some of the trickier integration points.

Setup Rails, RSpec, Cucumber, and Authlogic per their own documentation. I ended up with the following in both config/environments/test.rb and config/environments/cucumber.rb:# There is some duplication between test.rb and cucumber.rb.
config.gem "cucumber", :lib => false, :version => ">=0.3.11"
config.gem "webrat", :lib => false, :version => ">=0.4.4"
config.gem "rspec", :lib => false, :version => ">=1.2.6"
config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.…

Software Engineering: A Book on $foo

Rant warning:

I'm reading a new book. Let me summarize:$foo is awesome. It will help you get your projects done on time and on budget. Traditional software projects fail because they don't use $foo. The people who do manage to deliver software on time and on budget only do so because they are heroic programmers. Their process is actually fighting against them. They should use $foo instead. Traditional software projects fail because they deliver the wrong features too late. This is because they use the waterfall approach to software design instead of using $foo. If you use $foo, you'll deliver your software on time and on budget, you'll have fewer bugs, and you'll have fun doing it!Like, gag me with a spoon! Books been coming up with new approaches, making the same promises, and criticizing the same waterfall model since the '70s!

Ok, here's a fun idea. Come up with a design book that doesn't criticize the waterfall model, but criticizes some ot…

IDE: NetBeans after Six Months

I've been using NetBeans for six months. I thought I'd whip out a quick post to tell you how it's gone. My earlier post is here.

I found a bunch more things I like. I finally figured out how to open files quickly. In the Projects window on the top left, click on the name of the project. Now, typing one letter at a time, you can get autocomplete. It took me a little while to figure out how it works, but now I can open files more quickly than I can visually parse things.

I also figured out that if I maximize the editor, and I shrink the size of the whole window, I can get the editor to fit in smaller places without taking up the whole desktop. That's helpful when I'm copying code I'm reading from a PDF to NetBeans even though I only have a 13" MacBook screen. (I like to manually copy code samples when I'm reading a book in PDF form because it helps me to learn the code better. I'm stuck with a tiny screen because I do a lot of my work at Starbu…

Agile Programming: I'm Stuck in the Middle

I found out yesterday, that at least according to Xmarks, my blog is far more popular than even I thought. However, before you think my head has gotten too big, let me tell you about two companies I interviewed with recently that turned me down. Twitter turned me down a couple years ago, and Aardvark turned me down a couple weeks ago (which is really a shame because I think Aardvark is awesome!).

Both of them said pretty much the same thing. They said I was too methodical and relied too heavily on documentation. More importantly, I'm sure, was that I didn't yet embrace test-driven development, TDD.

In TDD, you write your tests first, and then you write your code. However, ever since college, I've written my docstrings first, and then I write the code. I generally write the tests after I've written some code, and then I grow the two together. Although, I don't practice TDD, I am test infected, which means I feel uncomfortable about code that I've written un…

Rails: Internationalization

I'm reading through Agile Web Development with Rails. I'm surprised at how naive the I18n support in Rails appears to be.

It seems to get number formatting right, but it gets a lot of other things wrong. For instance, as far as I can tell reading the book, it assumes all languages have the same pluralization forms as English. It forces you to create YML-based "constants" for all your localization strings. Hence, your templates contain things like I18n.t('checkout.submit') instead of, say, _("Submit your order"). I have no clue what happens if you're missing a constant in your YML. I also don't think it understands how to degrade gracefully. For instance, if I ask for some weird sub-dialect, I bet it doesn't know how to fall back to the main language. Furthermore, the YML files painfully duplicate strings for translation. I haven't seen anything for dealing with the Accept-language header, but that could just be the book's…

Rails: Validating URLs

Here's a quick-and-dirty way to validate URLs in your model. Updated: Only allow certain schemes.require 'uri'

class Film < ActiveRecord::Base

VALID_URI_SCHEMES = ['http', 'https']

validates_presence_of :url
validate :url_must_be_valid


def url_must_be_valid
parsed = URI.parse(url)
if !VALID_URI_SCHEMES.member?(parsed.scheme)
raise URI::InvalidURIError
rescue URI::InvalidURIError => e
errors.add(:url, 'is not a valid URL')