views:

15

answers:

1

Hi,

I run a Ruby on Rails website that have multiple domain names. I have a "Website" table in the database that stores the configuration values related to each domain name:

Website
- domain
- name
- tagline
- admin_email
- etc...

At the moment, I load the website object at the start of each request (before_filter) in my ApplicationController:

@website = Website.find_by_domain(request.host)

The problem is when I need to access the @website object from my model's methods. I would like to avoid to have to pass @website everywhere. The best solution would be to have something similar to APP_CONFIG but per domain name.

def sample_model_property
- - "#{@website.name} is a great website!"
end

How would you do it?

A: 

If this is a controller instance variable, then you should have access to @website everywhere you require it both the Controller and View domains. If you need to push something through to the Model space in the same capacity, you either have to pass it, or hack it in via something like the model_helper method.

What you might do instead is use a kind of singleton method on your Website class, for instance:

class Website < ActiveRecord::Base
  cattr_accessor :current_website
end

Then in the controller you can do things like:

before_filter :load_current_website

def load_current_website
  Website.current_website = Website.find_by_domain(request.host)
end

That way you can refer to Website.current_website anywhere within the model space and things should be in sync. Note that this may not be entirely thread safe and should be tested extensively in a production-like environment before using it.

tadman
Wouldn't Website.current_website point to the same object across all my websites if I am running on the same application?
Aymeric
That ties in to my "thread safe" comment. In a single process, single thread environment you can use a global variable such as this with little risk. If you have multiple requests being processed simultaneously this will not work. This is partly why passing it in each time is the safest method, as annoying as it can be.
tadman