DDD Aggregates in Rails with ActiveRecord
In Domain Driven Design there is a concept of an Aggregate.
A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the Aggregate, designated as the root.
Simply put: an aggregate has one entity that is designated as the root and an object of the root's class is what you would manipulate in your code. The other entities in an aggregate could not stand on their own outside of the aggregate. It is possible to use the aggregate concept using just ActiveRecord in Rails.
Top Chef: Cloud Edition
Lately at Pure Charity I’ve been using Chef to build our infrastructure on Amazon’s EC2. After using chef for the last few weeks I have come to fully embrace it and I will never again build a Linux box by hand. I know that sounds pretty dramatic, but if you build servers (in the cloud or bare metal) you NEED to do yourself a favor and look at Chef. In the coming week I’m going to write a series of posts about Chef. This week I’m going to explain what Chef is and why it matters.
My World Through Vim Colored Glasses
I like Vim. I like it a lot. I’m sure Emacs is good to, but I’m flying the Vim flag. I used to use a Big Enterprise IDE™ but I have found that Vim gives me a lot of power without using all of my memory to run an IDE.
Through all my years of experience with Vim, I have become more and more proficient with the Vi keybindings. For example I used to rely on the arrow keys when I started using Vim, but now h/j/k/l have become my preferred way to navigate. I find myself exiting insert mode more often than not to accomplish tasks, compared to spending almost all of my time in insert mode.
With this ever growing proficiency, I find my interactions with everything else…a bit lacking. My terminal feels slower, my IRB sessions feel slower, I wanted to be able to use my Vim-fu everywhere. After some digging and investigating I found ways that I could do it.
Demystifying Ruby’s case-when Statement
Today I was writing some code to check the type of a method parameter. I opted to use a case statement for better clarity. To my surprise I was able to simply pass the name of the class. So this got me thinking about the internals and how case-when actually works.
The case-when statement is using the === method to perform the match in the
when clause of the statement.
For example, following two pieces of code are equivalent:
case 1 + 1
when 2 then puts "win"
end
if 2 === 1 + 1
puts "win"
end
Take note of the comparison, the when clause is compared to the case clause. I
thought it would be the other way around, but this makes sense.
So to create your own classes that match this condition then you would have to
simply implement the === method:
class AlwaysMatches
def self.===(value)
true
end
end
case :something_crazy
when /\w+_sane$/ then "this won't match"
when String then "this won't match either"
when AlwaysMatches then "Game...Set..."
# => "Game...Set..."
This class will always return true when compared in a case-when but if compared
in an if statement with an equality operator will return false unless compared
with itself.
The potential usage I see for this is if you have written a class that can compare with Ruby’s primitive types.
Setting up Wildcard Subdomains on OS X 10.6
The new trend in web applications is to have your customers name or account code in the URL as a subdomain. Like in 37 Signals Campfire web application the URLs look like: myaccount.campfirenow.com. This is pretty cool because is gives your customers a little bit of customization and it is one less thing that you have to maintain in your session state store. It makes development a real beating though because most of the time you have to maintain a set of accounts in your /etc/hosts file. I’m going to walk you through getting all the subdomains you want with a little upfront configuration.
I know that the Passenger PrefPane and other solutions like Pow handle this for you, but I prefer to run the same server for development that I will be running in production and I currently use Unicorn on all my production apps. I won't go into setting up Unicorn, but I just set up the standard Nginx reverse proxy to Unicorn configuration.