RSS has_many :through - home

http://blog.hasmanythrough.com

Last checked about 1 hour ago.

49 people have subscribed to this feed.

Feed frequency

post frequency (last month)

PostRank™ filter

latest 15 posts

« older items




Tuesday September 23rd, 2008

4.4

Hello, New York

has_many :through - home From has_many :through - home, 14 days ago, 0 comments Comment

By way of the obligatory sorry-I-haven't-blogged-much-lately apologette, I should say that life has been busy this summer. The second biggest deal for me was, get this, moving to New York City. Yes, I know I just moved to a new place in San Francisco, and no, I haven't given up on my favorite city. It's a temporary move and I should be back in SF by the end of the year. What happened is that Pivotal Labs has opened an office in Manhattan, and I've come out to work on client projects and help get the office going. The takeaway on that is that Pivotal Labs is available for projects in New York, and we're also looking to hire top-notch Rails developers to work with us here.

The word I have to pick to describe New York is vital. That's true of the city in general, but from what I've heard it's also true of the Ruby development community. I am looking forward to getting to hang with folks here and see what I can learn from the other coast. There's a lot of Ruby developer events around here. I'm going to start with the nyc.rb hackfest tomorrow.

While I'm out here on the East Coast, I'm going to hit up some conferences. In November I'll be attending RubyConf 2008 in Orlando. Then later that month I'll be at the Voices That Matter: Professional Ruby Conference, giving a talk entitled "Ruby: Fragile or Agile?"

In the mean time, where's the best pizza in New York?

Sunday August 17th, 2008

5.1

Sorting things out

has_many :through - home From has_many :through - home, 1 month ago, 0 comments Comment

I recently packed up everything I own and moved. I'd lived in my old place for about nine years and I have the packrat gene on both sides of the family tree, so I had a lot of crap to sort through to figure out what to move and what to trash, as well as which box what should go in. Now that I'm here in the new place, I've had to sort through the remaining stuff to figure out where it all goes. So you might appreciate that sorting has been on my mind a lot lately. (See? It's a topical tie-in. I don't do those often, so I hope it wasn't too awkward.)

I've also been working on an application that does a lot of sorting to prioritize tasks in a workflow. These items often need to be sorted based on multiple criteria, such as how long an application has been waiting for approval, how many times a customer has been called recently, etc. We also have to sort names that have anywhere from two to four components (Hispanic names can have both paternal and maternal names instead of just a surname).

Friday June 20th, 2008

5.6

Extra geeky: the recursive lambda

has_many :through - home From has_many :through - home, 3 months ago, 0 comments Comment

I'm not sure where I first heard that you could do a recursive lamdba in Ruby, but it's been simmering on the back burner of my brain for a while. I've just never had a reason to use one, until now...

I wanted to process the Rails request params, which is a hash of strings and hashes of strings and hashes of strings and hashes... you get the idea. The need was to strip all the accent marks from user input throughout the application. Here's what I came up with:

class ApplicationController < ActionController::Base
  before_filter :strip_accents

  protected
  def strip_accents
    thunk = lambda do |key,value|
      case value
        when String then value.remove_accents!
        when Hash   then value.each(&thunk)
      end
    end
    params.each(&thunk)
  end
end

That's all completely clear, right? The filter enumerates the top-level hash using the &/to_proc operator to coerce the lambda to a block for the #each method. #each passes the key and value to the lambda, which either removes the accents from a string, or recursively enumerates the contents of a nested hash.

I think it's totally cool that you can do this in Ruby. Everyone thinks that Ruby is just an object-oriented language, but I like to think of it as the love-child of Smalltalk and LISP (with Miss Perl as the nanny).

Sunday June 15th, 2008

2.7

An extra special case

has_many :through - home From has_many :through - home, 3 months ago, 0 comments Comment

A couple of months ago I ran into a weird issue in my current Rails project that made no sense at all. All we did was add a lock_version field to a model to enable optimistic locking and suddenly things started breaking in a big way. After a bit of digging we found it was because ActiveRecord wasn't properly quoting a table name when updating a record with optimistic locking. I submitted a patch for that issue (so it's fixed in Rails 2.1), but lately I've seen a few similar bugs having to do with table name quoting in various circumstances. The amusing thing to me is that all of these bugs have one thing in common: they were uncovered by creating a model named Reference.

At first I thought this was a pretty big coincidence, but after just a moment's thought it seemed pretty obvious. ActiveRecord pluralizes model names to form conventional table names, and references is a reserved keyword in MYSQL. I guess Reference is a word that makes a good model name, especially if you're building a big data graph and can't think of a more specific relationship name, and it's about the only noun that pluralizes into a reserved keyword that anyone would ever use. In our case, we could have done a rename refactoring to change the model class name to CharacterReference. Instead we used an override and changed the table name to t_references, since that seemed like the least effort for a temporary workaround until the fix got released with Rails 2.1.

All these various issues with table name quoting are indeed bugs in ActiveRecord and should be reported and fixed. (There's also a major reworking of the internals of ActiveRecord in progress that should deal with virtually all of these issues in one fell swoop.) But in the mean time, you might want to avoid using model names that generate SQL reserved words, or just override the table name to something else.

Sunday June 1st, 2008

4.4

The Great Test Framework Dance-off

has_many :through - home From has_many :through - home, 4 months ago, 0 comments Comment

Got my RailsConf talk done yesterday. Seems to have gone over well, though my slides didn't show color well in the brightly lit room so they turned the lights down all the way to see them better and I ended up doing the talk as a ghost story for half of it. Guess I have to revise my rules for slide creation to account for ambient light.

Anyway, I have a PDF of the slides posted: The Great Test Framework Dance-off. I've also opened up the example code and tests on github as the teldra_prime project. That project is based on the application that runs this blog, but you should probably avoid deploying it to run your own blog. I'll be releasing the Teldra blog software as its own project very soon, and that will be the project where I continue development and people can contribute changes.

Also, it turns out I have a craaaaazy fan. Here's a picture of us at the end of the talk, me posing with his ballpoint tattoo of me on his bicep. Yes, somebody drew picture of me on his body! That so beats people introducing themselves at the urinal!

Saturday May 31st, 2008

5.9

Quick RailsConf Update

has_many :through - home From has_many :through - home, 4 months ago, 0 comments Comment

Quick RailsConf Update

DrNic complained about the lack of blogging from RailsConf, so here's a quick little update with some highlights. It's still early here and I have to get to breakfast soon, so I have to be brief.

First impression: lots of people. Second impression: "they want us all to fit in there?"

I called it exactly right. Joel Spolsky tried to pull a Ze Frank and did some random crazy presentation in his keynote, but it fell pretty flat. It was really polished and fairly amusing, but I was often insulted by either his blatantly sexist attempts at humor or his estimation of the audience's intelligence. It was nearly entirely content-free, and while he tried to develop a theme about the importance of esthetics, he never went anywhere with it. If you missed it, count yourself lucky.

On the other hand, David Heinemeier Hanson did a keynote where he transformed himself from a technologist into a life coach. His talk on The Great Surplus was interesting, if only to get a glimpse of the world from his perspective. I think most of what he said was right on, especially the bit about how everyone should code less and sleep more.

One of his points was his expectation about how Rails might lose its productivity advantage. He said there were three options: 1) Mainstream tech copies Rails' good points, 2) A radically new tech outdoes Rails, and 3) Rails becomes mainstream so there is no longer an advantage. But I think there is a 4th option. It's what happened to Smalltalk. I'm talking about C++. We Smalltalkers used to think the advantages of our language were so significant that it would take over the world. We had a huge productivity advantage over C coders. Then C++ came along and gave C coders just enough to let them improve their productivity and their ability to write larger more complex systems. It still wasn't as good as Smalltalk, but it was better than C, and much more accessible to most programmers than Smalltalk. C++ eventually sucked up all the oxygen and Smalltalk is now only a language for hobbyists and the occasional programming god. I think this is the most likely threat to the Rails surplus, that C# or Scala or something can do a good enough job that people can double their productivity with far less of a change in mindset or tools, and eventually no one will care about the ten times (or whatever) productivity of Rails. "Good enough is good enough."

Last bit before I gotta run. I've heard rumors about MagLev for a while, and the early announcement last month got me really excited. The demo and discussion yesterday by Avi Bryant and Bob Walker was one of those jaw-droppers that had everyone in the room freaking out. What they showed was pretty spectacular, though I always like to keep in mind Lansford's Corollary to Clarke's Third Law: "Any sufficiently advanced technology is indistinguishable from a rigged demo." The staggering performance boost together with the scalability and seamless integration of persistence could be a serious game-changer. I think the GemStone OODB technology beats the pants off of the ORM approach for most web applications, and if they can pull this off it's going to have a huge impact on how I write my software.

I'm giving my talk today at 4:25pm. Yes, I still freak out about giving talks. As critical as I can be of others, I'm hardest on myself. I hope I don't give myself too lousy a review when I'm done, heh.

Wednesday May 28th, 2008

1.4

See you at RailsConf

has_many :through - home From has_many :through - home, 4 months ago, 0 comments Comment

Seems like only last week that I was in Portland for RailsConf, but it was a whole year ago. That means it's time to do it again. I'm looking forward to the conference and getting to soak in all the Railsness. The program looks excellent this year, though I doubt Joel Spolsky can top Ze Frank or _why.

I always like to meet my readers, so please do say hi. If you want to know where to find me, I've got a few fixed points on my schedule:

  • 7:30pm Thursday - Pivotal Labs BoF. We were going to talk about our open source projects, but instead we're going to talk about the agile development process and Rails.
  • 12:30pm Friday - Book Signing. I've got a recipe in Mike Clark's new Advanced Rails Recipes book, and a bunch of us contributors will be signing copies. Look for us in the Powell's Books booth. I'm pretty sure Mike is buying me some Scotch for this, so make it worth his while.
  • 4:25pm Saturday - The Great Test Framework Dance-off. I'm doing a talk comparing the most popular test frameworks. I don't know if it will be Adam Keyes level great, but I promise there won't be karaoke.
  • 9:00pm-Midnight Saturday - Pivotal Labs Beer Night. Free drinks, food and pool. At the Rock Bottom Brewery, 206 SW Morrison St.

Also we're raffling off a Nintendo Wii in our swiipstakes on Saturday. Come to the BoF on Thursday to get one of our shirts, or if you can't be there you can make nice with a pivot later to scam one if we have extras. If a pivot spots you in a shirt over the next three days you can get a raffle ticket. (Wear the shirt while presenting a talk to get two tickets!) Then come to the beer night for the Wii raffle (must be present to win).

Tuesday May 6th, 2008

5.6

A simple alternative to namespaced models

has_many :through - home From has_many :through - home, 5 months ago, 0 comments Comment

A project I'm working on now is up to 57 model classes and is still growing. That's a lot of classes - welcome to domain modeling. In my opinion, the number of classes is a fair tradeoff that keeps each class simple enough to understand. In some ways it moves complexity out of the model class internals into the inheritance hierarchy, which is an important part of object-oriented design. I've worked on projects with many more model classes than that too. (Financial applications seem to require a lot of classes to model the complicated workflow and permission systems.)

The place where it starts to get hard to manage is when I look at the file system and see so many files in one directory. My brain usually starts to overload when I see more than a dozen or so classes in a directory. My first inclination is to throw some related class files into a subdirectory. The problem is that the standard way to do that in Rails is to put those models classes in a namespace (module). Rails used to have big problems with namespaced models, mainly with the dependency auto-loading code that finds class files based on the model class name. Most of those problems have been fixed, but there are still some usability issues with namespaced models.

Saturday April 19th, 2008

6.8

Symbols are not pretty strings

has_many :through - home From has_many :through - home, 5 months ago, 0 comments Comment

Symbols are one of the basic features of Ruby that give it that certain charm we all love. They aren't unique to Ruby (look at Smalltalk or Lisp), but they are a fundamental piece of the language. I'm not going to review what symbols are in this article since there are plenty of other explanations a short google away. However, I do want to say a few words about what I consider a common misuse of symbols.

The way I see it, symbols are great for naming things in your code, but bad for using as domain data. Over the last year or so I've seen a growing number of cases where symbols are used as an alternate syntax for plain old strings. I guess some people like to see :thing instead of "thing" in their code. Well, I don't like it. Sure you get to save a character, but at what cost? Won't somebody think of the children?

Thursday April 10th, 2008

1.9

GitHubba-hubba

has_many :through - home From has_many :through - home, 5 months ago, 0 comments Comment

If you hadn't heard, GitHub had their public launch today. Congratulations to Chris, Tom and PJ on such an awesome product. I'm sure there's a bright future there.

I keep getting surprised by how different using GitHub is for me. Last week someone I never met or had even heard of found my migration_condordance repo and submitted fixes for two bugs. It wasn't quite as big a thrill as my first kiss, but I sure got more of a rush from that than from seeing Beowulf in 3-D IMAX. On the other hand, when I saw someone else stopped watching my repo I was actually a bit sad. Yes, this is geek social networking with both value and impact.

You may have already seen that the Ruby on Rails is moving the official repo to GitHub. It's not active as of this writing, but give it a few hours. I'm looking forward to seeing what this does to the contribution process. I expect there could be a rich ecosystem of forks of Rails where you can see a bunch of variations integrated into a consistent whole. A lot of folks keep what is effectively a fork of Rails, but it's often in the form of a collection of monkey patches. Using git means that those patches can be managed more effectively, and even made available to the public in a form that can be easily consumed. Then it becomes much easier to evaluate whether a change has enough support to justify including it in Rails core - just see how many people are actually using the change, instead of merely of the opinion that it might be useful. I don't know how to track how many people are using a repo that way, but I'm sure someone will think of something - maybe just a count of how many clones were made or tarballs were downloaded.

At any rate, today feels like some kind of milestone. Or perhaps a furlongstone.

Wednesday April 2nd, 2008

6.8

simple pages

has_many :through - home From has_many :through - home, 6 months ago, 0 comments Comment

Simple things should be simple, complex things should be possible. — Alan Kay

Here's a tiny little tip for handling those boiler-plate pages that aren't part of your app's functionality but you usually need anyway. It's good for setting up about, contact, copyright, etc. You can always throw those pages into /public as static html files, but if you want them to get styled with layouts, they need to be rendered as actions. This is a way to do that simply. It's not rocket science, but I haven't done a noob post in ages and I'm getting over a cold and I haven't posted in too long so gimme a break.

Say you want to have a simple landing page and a few typical boiler-plate pages. Let's start with the routes.

In config/routes.rb

map.root :controller => 'home'
map.home ':page', :controller => 'home', :action => 'show', :page => /about|contact|copyright/

In app/controllers/home_controller.rb

def index
  # render the landing page
end

def show
  render :action => params[:page]
end

Throw your about.html or about.html.erb and other pages into app/views/home and you're good to go. If you've set up page caching, this won't even slow your app down.

The :page => /.../ bit in the route constrains it to match only those specific urls. If you want, you can change that to a constant, like HomeController::PAGES, so it's easier to manage.

If you want to link to those pages, you can use the route helper methods, home_path and home_url

link_to 'About', home_path('about')

You could always unroll the routes and have a separate route for each page, but I find this way a bit drier. But if you'd rather have a specific named route helper for each page, that's an okay way to go. Either way, you get to use layouts in your pages, and have a nice simple way to get them rendered.

Monday March 3rd, 2008

6.3

Migration Concordance

has_many :through - home From has_many :through - home, 7 months ago, 0 comments Comment

If you are a solo developer, Rails' migrations are the neatest thing since sliced bread. If you work on a team, you know that often it can be a real pain dealing with migrations. Someone on your team checks in a new migration and you don't notice it when you svn up or git pull, and suddenly all your tests are breaking. Or even worse, someone modifies an old migration and you need to reset and migrate up from zero (we're talking development here, not production). I'm not a fan of automatically running migrations (I'll leave the reasons for you to guess), but I do like to be informed of when I'm about to run headfirst into a wall. Saves so much wear and tear on my noggin.

And so I give you the migration_concordance plugin. It's pretty darn simple. From the README:

This plugin extends Rails migrations to provide notification when you need to run migrations. It will detect both new migrations and modifications to previously run migrations. It is primarily of use for team development, but is also useful when deploying a release to a new environment to determine when migrations need to be run. This plugin does not run migrations automatically, but will notify you whenever you need to run them.

Wednesday February 27th, 2008

6.4

count vs length vs size

has_many :through - home From has_many :through - home, 7 months ago, 0 comments Comment

In Ruby, #length and #size are synonyms and both do the same thing: they tell you how many elements are in an array or hash. Technically #length is the method and #size is an alias to it.

In ActiveRecord, there are several ways to find out how many records are in an association, and there are some subtle differences in how they work.

  • post.comments.count - Determine the number of elements with an SQL COUNT query. You can also specify conditions to count only a subset of the associated elements (e.g. :conditions => {:author_name => "josh"}). If you set up a counter cache on the association, #count will return that cached value instead of executing a new query.
  • post.comments.length - This always loads the contents of the association into memory, then returns the number of elements loaded. Note that this won't force an update if the association had been previously loaded and then new comments were created through another way (e.g. Comment.create(...) instead of post.comments.create(...)).
  • post.comments.size - This works as a combination of the two previous options. If the collection has already been loaded, it will return its length just like calling #length. If it hasn't been loaded yet, it's like calling #count.

That's I always have to look up these differences, so now I have them in one place so I don't have to think about it anymore.

By the way, today is my blog's second birthday. I just couldn't let that go by without a post!

Thursday January 31st, 2008

6.8

Segregated page cache storage

has_many :through - home From has_many :through - home, 8 months ago, 0 comments Comment

Page-caching is one of the highest leverage features in Rails. It doesn't take much to set up, and the payoff is huge. When building Teldra I knew from the start that page caching would be part of my production deployment, as it should be for any site with pages where content changes infrequently relative to number of views.

The only thing I find annoying about using the page caching feature is how the cached pages are stored in the RAILS_ROOT/public directory, right alongside all the app's other static pages. I greatly prefer having the cached pages stored in a separate directory. This makes it a lot easier to distinguish between static pages and cached dynamic pages, and if something goes wonky with your cache you can blow it away easily with a single command.

Saturday January 26th, 2008

2.9

Feed readers are lame and URLs are forever

has_many :through - home From has_many :through - home, 8 months ago, 0 comments Comment

When I changed my blog software from Typo to Mephisto, my article and feed URLs all changed. I didn't want to break all those old URLs, so I put a lot of effort into writing a ton of Apache mod_rewrite rules to redirect the old URLs to the new ones. I set them up as 301 permanent redirects to indicate that the old URL was defunct and to use the new one from then on. That means that the feed reader is supposed to change the URL for the feed permanently. But feed readers are lame and many treat the redirect as a temporary change, so I'm still getting requests for feed URLs that haven't existed in over a year.

If you're reading this article in your browser because your feed broke and you came here to see what happened, that means it's time to update the URL for your feeds. I'm sorry, but your feed reader has been told every hour for the last year that the URL has moved to a new location forever, but it chose to ignore that fact, and I'm not going to keep supporting those old URLs anymore. Here's the new URLs so you can manually update your feeds:

The main feed is hosted on FeedBurner: http://feeds.feedburner.com/hasmanythrough (and has been for the last year).

Categories have disappeared and articles are now organized only by tags. Old categories are now just tags. Tag feed URLs look like: http://blog.hasmanythrough.com/tag/rails.atom

I haven't set up comment feeds yet, but they should be along in a week or two at most.

« older items