TL;DR

We moved a Rails app into an unbuilt engine of a new blank slate container app to allow new parts of our app to live next to it as engines as well. It has been working great for us!

I have a sample app rails_container_and_engines of the result's structure on github.

Skip to the pitfalls and discoveries section to read about some of the speed bumps we during our transition. Interested in the why and how? Read on!

Josh SusserJosh Susser
Simple DRY Validations
edit Posted by Josh Susser on Monday September 14, 2009 at 09:30AM

Here's a handy trick for making custom validations easily reusable.

This is an extract from a customer model with three different street addresses, in which we validate all three of the zip codes. (In this code, the GeoState.valid_zip_code? method answers if something that looks like a zip code is an actual zip code - not all five digit combinations are in use as zip codes, and we want to make sure we've got a live one.)

def validate_home_zip_code
  validate_zip_code(:home_zip_code)
end

def validate_mailing_zip_code
  validate_zip_code(:mailing_zip_code)
end

def validate_previous_zip_code
  validate_zip_code(:previous_zip_code)
end

def validate_zip_code(field)
  errors.add(field, :inclusion) if errors.on(field).nil? && !GeoState.valid_zip_code?(send(field))
end

validates_presence_of :home_zip_code
validates_format_of :home_zip_code, :with => /^\d{5}(-\d{4})?$/, :allow_blank => true
validate :validate_home_zip_code

validates_presence_of :mailing_zip_code
validates_format_of :mailing_zip_code, :with => /^\d{5}(-\d{4})?$/, :allow_blank => true
validate :validate_mailing_zip_code

validates_presence_of :previous_zip_code
validates_format_of :previous_zip_code, :with => /^\d{5}(-\d{4})?$/, :allow_blank => true
validate :validate_previous_zip_code

That looks very wet to me. (WET == "Write Every Time") But it's not too hard to dry this up using just a tiny bit of knowledge of how ActiveRecord validations work.

Adam MilliganAdam Milligan
Refactoring a dead horse
edit Posted by Adam Milligan on Sunday May 10, 2009 at 05:30PM

A while back I made the point that the HasOneThroughAssociation class in Rails shouldn't be a subclass of HasManyThroughAssociation. I also submitted a Rails patch in which I changed the superclass of HasOneThroughAssociation from HasManyThroughAssociation to HasOneAssociation and moved the shared Through functionality into a module. Despite support from the teeming millions, Rails core team member Pratik rejected the patch for being "just a refactoring."