RSS has_many :through - home

http://blog.hasmanythrough.com

Thursday January 31st, 2008

6.8

Segregated page cache storage

has_many :through - home From has_many :through - home, 11 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, 11 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.

Friday January 25th, 2008

1.8

Speaking at RailsConf 2008

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

I received word this week that my talk proposal for RailsConf 2008 has been accepted. I'll be giving a talk called The Great Test Framework Dance-off. Doesn't that sound like fun?

Thursday January 24th, 2008

2.8

One Hundred, Two Hosts, Three Engines

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

I started this blog nearly two years ago. In its first incarnation, it was running on the venerable Typo engine, hosted on DreamHost. About a year ago I switched over from Typo to Mephisto, still on DreamHost. Typo was a great start for me, and Mephisto was a good change when Typo was having some issues with the project. (Typo seems to be back on track these days, and has been for a while.) DreamHost was really cheap to get started on with hosting a Rails app, but I outgrew it in a couple months and have just been living in pain and denial ever since.

Now it's nearly two years later, and this is my 100th post on this blog. Coincidentally, it's another big transition for me. As of now this blog is hosted by the awesome force of nature that is EngineYard, and it's running on blog software of my own creation.

Thursday December 20th, 2007

5.0

Book Review: The Rails Way

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

Here's another entry in my ongoing Rails book review series.

Title: The Rails Way
Author: Obie Fernandez
Publisher: Addison-Wesley

The latest entry in Addison-Wesley's Professional Ruby Series is The Rails Way, by Obie Fernandez. The name is a nod to Hal Fulton's noble classic The Ruby Way, and it's clear this book aims to be as significant a feature in the Rails publishing landscape. The good news is that the book delivers, and then some. The Rails Way appears destined to become the new bible of Rails development.

Before I dive into the full review, a disclaimer. Obie is a friend and fellow cabooser, and someone I have a lot of respect for. I just want to get that out of the way so that no one can say I'm shilling for his book on the sly. But I'm glad I can give him a good review with a clear conscience. Anyway, back to the review.

Tuesday November 13th, 2007

2.2

step, step, pivot, step

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

Wow, RubyConf was awesome. I'm sure by now you've read all the various blog reports on the sessions and the werewolf attacks. Aside from some stupid, amazingly loud all-night construction across the street from my hotel room, the conference was great and I had a superb time. It was very cool to see how far alternate Ruby VMs have come, and I expect the next year to be very interesting in that area. By the way, RejectConf has become too mainstream. What's up with doing it in a real conference room with A/V support and everything? And what about the beer?

Thanks to everyone who introduced yourself to me as a reader. (Though in the future you might want to wait until I've washed my hands and left the bathroom.)

The QCon panel last week was fun too. The topic was When is Rails an Appropriate Choice? James Cox did a nice job of running things, and I got to spend an hour talking with Obie Fernandez, Charlie Nutter and Ola Bini. (There were some last-minute changes in the lineup.) The panel was recorded on video, so I'm guessing InfoQ will make that available at some point.

Oh yeah, some news. Last week I started work at Pivotal Labs here in SF. Pivotal is a real powerhouse consulting firm specializing in web app development and does work in both Java and Ruby on Rails. The Rails developers there are top-notch and I'm really happy to be part of such a talented team. If you haven't been reading the company's coding blog Pivotal Blabs, you've been missing out. While I was having fun consulting and getting to work on lots of different things, I was missing having a regular schedule and co-workers who lasted more than a short time. This way I get the best of both worlds. I also get to work in an environment with a solid commitment to good development practices. My new job title is "Senior Agile Engineer", which should tell you something even if it mystifies the bank next time I apply for a loan.

Tuesday October 30th, 2007

7.0

Self-referential has_many :through associations

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

This article updates a previous version for the Rails 2.0 way of things. Since there's not much difference, I decided to fix up the example code to be more understandable. After all, not everyone is a discrete math geek.

This example updates the one from the previous article. The only significant difference is that you don't need to specify the :foreign_key when using the :class_name option in a belongs_to association. In Rails 2.0, the key is inferred from the association name instead of the class name. I also included the :dependent option because I feel it's too often overlooked.

These classes could be used to model a food chain. Spider eats fly, bird eats spider, cat leaves bird on pillow as gift...

create_table :animals do |t|
  t.string :species
end
create_table :hunts do |t|
  t.integer :predator_id
  t.integer :prey_id
  t.integer :capture_percent
end

class Animal < ActiveRecord::Base
  has_many :pursuits,  :foreign_key => 'predator_id',
                       :class_name => 'Hunt',
                       :dependent => :destroy
  has_many :preys,     :through => :pursuits
  has_many :escapes,   :foreign_key => 'prey_id',
                       :class_name => 'Hunt',
                       :dependent => :destroy
  has_many :predators, :through => :escapes
end
class Hunt < ActiveRecord::Base
  belongs_to :predator, :class_name => "Animal"
  belongs_to :prey,     :class_name => "Animal"
end

The Hunt model describes how likely a species of predator is to catch a species of prey. From the predator's perspective the hunt is a pursuit, but the ever-hopeful prey sees it as an escape. Note that you can model both kinds of hunts between the same pairings of animals: Some days you get the bear, some days the bear gets you.

1.2

RubyConf and QCon

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

RubyConf 2007 is just a few days away. I'll be there in Charlotte, basking in the Ruby love. If you're there, do say hi. I always like meeting my readers.

Also, I'll be at QCon in San Francisco next week. On Friday afternoon I'll be speaking on James Cox's panel: When is Rails an Appropriate Choice?

Monday October 29th, 2007

5.3

Book Review: Pro Active Record

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

I've been wanting to start doing some book reviews for a while, so here goes. The folks at Apress have been kind enough to send me review copies of a couple books, so I'm going to start with one of them. First up, Pro Active Record.

Title: Pro Active Record: Databases with Ruby and Rails
Authors: Kevin Marshall, Chad Pytel, Jon Yurek
Publisher: Apress

My first thought at seeing this book was, "Hey, a book all about ActiveRecord! Cool!" It's nice to finally see a volume dedicated to ActiveRecord, since it's my favorite part of Rails. However, this book ends up being something of a mixed bag. There's a lot of good information in it, and it does a decent job of covering all the basics. There are even some excellent parts here and there. But the book also has some problems, so it's hard for me to give it an unequivocal recommendation. Nevertheless, it does have value and fills a needed spot, so it may be what you're looking for.

Wednesday October 24th, 2007

5.5

MicroPlace: invest wisely, end poverty

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

And now for something completely different... I'm talking about the launch today of MicroPlace, a new website which was written in Rails. I don't usually call out such sites, but this time is different for a few reasons. Firstly, I helped build the site, so I have a personal involvement in it. Secondly, it's a good cause that's worth talking about. And lastly, the circumstances of its creation should be of interest to the Rails community.

Thursday October 18th, 2007

7.5

Simpler than dirt: RESTful Dynamic CSS

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

Way back when, I wrote about how to do Dirt Simple RCSS in Rails. Now that Rails 2.0 is upon us, it's time to get even simpler. With all the restful magic in Rails 2.0, you can get even simpler than dirt.

Let's assume you have a restful User resource. You've got your "map.resources" in routes.rb, a typical User model, and a Users controller with standard views like index and show. Now you want to generate user-specific css based on state in the user model.

1) Create a view template called "show.css.erb". For example:

p {
  color: <%= @user.color %>;
}

2) Add a css format option to the respond_to block in the show action of the UsersController. You only need the default behavior for the css format, since all you need to do is render the view.

def show
  @user = User.find(params[:id])
  respond_to do |format|
    format.html
    format.css
  end
end

You can see the dynamically generated css at a url like /users/1.css in your browser.

Here's how to use the stylesheet in a view, assuming you've set up a @user object:

<%= stylesheet_link_tag formatted_user_path(@user, "css") %>

Told you it was simple.

Note: Geoffrey "topfunky" Grosenbach also has a good article on dynamic CSS, which includes a nice screencast as well.

Monday October 1st, 2007

5.3

Everything old is new again

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

As you've likely seen in your feed reader about 50 times already, Rails is turning 2.0. The Preview Release has just been announced, which means that 2.0 final is just a few release candidates away. So much has changed over the last year or so that a lot of the older material on this blog is out of date and needs updating for the reality of 2.0. Seems like now is a good time to get going on the rewriting. I'll be digging in and bringing stuff up to date over the next few weeks (months? there are quite a few articles after all).

Here's the list of articles I'm going to be taking a look at. I'm not certain that all need updates, but I think most of them do. If you have a request for something in particular for me to work on sooner, just leave a comment and I'll take that into account. Of course, I'll be updating the Many-to-many Dance-off first!

New association goodness in Rails 1.1 New association goodness in Rails 1.1, part 2 The other ways :through The other side of polymorphic :through associations Why aren't join models proxy collections? Many-to-many Dance-off! Self-referential has_many :through associations has_many :through gets :uniq When associations aren't enough When associations aren't enough, part 2 Working with the relationship model CRUDdy searches How dynamic finders work New on edge: Magic join model creation Finding unassociated objects Basic Rails association cardinality Using faux accessors to initialize values

Monday September 10th, 2007

4.2

it's easy being redgreen

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

I can't get by without redgreen to colorize my test output. You can get it to work with all your Rails test tasks by requiring the redgreen gem in test_helper.rb. The problem is, it messes up your test output formatting when you run tests in TextMate using Command-R. The solution is trivial - check to see if any of the TextMate execution environment variables are present:

In test_helper.rb:

require 'redgreen' unless ENV['TM_MODE']

Now back to your regularly scheduled internets...

Wednesday August 8th, 2007

6.1

Show flash messages on cached pages

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

If you've ever used Rails page caching, you've probably run into the situation where you wanted to cache a page that had essentially static content, but couldn't because it showed a flash message. I ran into this recently, and thought it would be really slick to move the flash rendering from the server to the browser, so that the page content could be cached but the flash could still be rendered from a cookie. I mentioned my idea to a friend over at Pivotal Labs and he said "Oh, we did the same thing just last week." What they did was very close to what I wanted, and they were ready to release it to the wild, so I sat down with pivot Brian Takita and spent a little while working with him to extract the feature, document it and package it as a Rails plugin.

The result: the Cacheable Flash plugin. Brian's post has a good description, but also checkout the README. For the moment this affects the flash for all actions in a controller, but Brian and I are looking into :except/:only options to allow finer-grained control if that is ever needed.

To install:

ruby script/plugin install svn://rubyforge.org/var/svn/pivotalrb/cacheable_flash/trunk

Thanks to Brian and Pivotal for this slick contribution. (By the way, doing TDD in JavaScript with JS-Unit is pretty freaking cool.)

Tuesday July 17th, 2007

6.0

on edge: inferred foreign key name change

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

Here's a change that has been a long time coming. (Really. The first time I heard DHH mention he wanted to do this was in March of 2006.) I liked it so much that I've been playing shepherd for it to make sure it happens. So if you're on edge, now is the time.

In 1.2.x and previous, the name of the foreign key of a belongs_to association is inferred to be the name of the association's class plus "_id". The class is inferred to be the camel-case equivalent of the association name, so in the simple case the foreign key ends up the same as the association name plus that "_id". For example: :line_item >> LineItem >> line_item_id. But if you explicitly set the class to something other than the default, the foreign key got inferred from the class instead of the association name. Example: :manager <> Employee >> employee_id.

Pre 2.0:

class Employee < ActiveRecord::Base
  belongs_to :manager, :class_name => "Employee", :foreign_key => "manager_id"
  has_many :employees, :foreign_key => "manager_id"
end

As of now (and thus in 2.0), when the class is explicitly set, the foreign key will be inferred from the association name instead of the class. For example: :manager <> Employee >> manager_id.

In edge/2.0:

class Employee < ActiveRecord::Base
  belongs_to :manager, :class_name => "Employee"
  has_many :employees, :foreign_key => "manager_id"
end

Why is this an improvement? Oh, it just saves a little typing.

class Article < ActiveRecord::Base
  belongs_to :creator, :class_name => "User"
  belongs_to :updater, :class_name => "User"
end

class User < ActiveRecord::Base
  has_many :creations, :class_name => "Article", :foreign_key => "creator_id"
  has_many :updates,   :class_name => "Article", :foreign_key => "updater_id"
end

Notice that you still need to be explicit about the foreign key name in the has_one or has_many associations. It would be a little nicer to be able to say something like :using => :creator in the has_many, but for now that's just a pipe dream.

« older items