Category Archives: domain

Reality check: is your project meaningful?

Here is a simple reality check for you: do models (entities) in your project tend to have names like Item, Content, Object, Data or ContentItem? If so, your project may not be meaningful to your users. You’re probably going to (or already do) have problems in communicating with them.

You see, the end users and domain experts don’t think in this terms. They don’t order “items” to build some “thing”. They order laser cannons and remote controllers to build a giant laser-beam-shooting, remote-controlled robot.

Giant Robot

That's what they're building.
So you better do a good job with what YOU are building.

If you call some entity an Object it means you don’t really know what it is and what it does. I bet the domain experts don’t call it an “object”, they call it “a part used to build a giant robot”. Can you see how much more information is given by a good name? Your “object” is a Part, so it has some technical characteristics, it belongs to some robot(s), it is probably stored in some warehouse, it may have a price, versions, dependencies, requirements, subclasses etc. This list could go on and on.

Laser Canon

A laser canon, not just an “object”…

On the other hand what does the name Object tell you? From my experience, it tells you that the developers don’t understand the users, the users don’t understand (and hate) the application, the specs are missing or outdated and no-one is able to identify a single use-case for the system. In short, not much of a success.

So, what’s your favorite meaningless name?

Advertisements

Cookie handling in multi-domain applications in Ruby on Rails

My team is working on a multilingual multinational application in Rails (I know this sounds incredibly pushy but bear with me). The application is at susuh.de if you want to have a look at it, but it’s still alpha version.

In practice, this multi-multi-blah-blah means that we want to use both various national domains (like susuh.at, susuh.pl — those links don’t function yet, they are only examples) and various subdomains (like pl.susuh.de or en.susuh.pl). The national domains will filter content only to respective country (so susuh.de will only have content from Germany) and the subdomains will be used to change the default language for the national domain (so if you are an English-speaking person living in Germany, en.susuh.de is your place to go). The subdomain will also be important in multilingual countries like Switzerland.

Trying to implement this scheme we’ve run into problems with cookie domain handling in Rails. And cookie problems lead to session problems for users, like being erroneously logged out or loosing other settings.

Cookie Monster
Mandatory Cookie-monster reference (you wouldn’t believe how many hits from Google this provides).

It seems that there are two official (normal) ways of handling this — at least that’s what Google says. Either you set your default session options in environment.rb like this:

ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_domain] = 
  '.susuh.de'

Or you don’t set it at all.

The former lets you set cookies for any subdomain of susuh.de, like pl.susuh.de, but no other domain. The latter sets cookie independently for each subdomain, causing different cookies for pl.susuh.de, en.susuh.de and susuh.pl. Neither is what we really want.

Spice Girls
So tell me what you want, what you really really want?

What we really want is to have the same cookie for any subdomain of susuh.eu and a different one for any subdomain of susuh.pl and so on. Nota bene, I’m not talking about a Single Sign-On problem, this is on much more basic level. We tried experimenting with setting DEFAULT_SESSION_OPTIONS “on the fly” in before_filter, but found out that this is too late (basically, this sets cookie domain for next request).

Fortunately, all is not lost. If all else fails, start reading code. And that’s what I did. The “entry point” for Rails is defined in dispatcher.rb file. Glancing over the code, I noticed something new for me: a before_dispatch callback. Google agreed that this may be a way to go, giving us link to http://m.onkey.org/2007/10/16/dispatcher-callbacks, among others.

Here’s our solution:

require 'dispatcher'
module ActionController
  class Dispatcher
    def set_session_domain
      ApplicationController.session_options.update(
        :session_domain => "#{@request.host.gsub(/^[^.]*/, '')}"
      )
    end
    
    before_dispatch :set_session_domain
  end
end