I’m developing a single application that responds to requests from two
domains. Various parts of my code need to work differently depending on
the request’s domain.
The typical solution would be to do something like this:
class ApplicationController < ActionController::Base
before_filter :initialize_site
makes @site available to all controllers and views
def initialize_site
@site = Site.find_by_domain(request.domain)
end
end
class Site < ActiveRecord::Base
def find_by_domain(domain)
# …
end
end
The problem is that I’d really like to have access to @site in my models
as well, because it would make my controllers much much more DRY.
In this (contrived) example, imagine two seperate store-fronts, both
selling widgets from the same manufacturer. But we want some widgets to
appear in one store, and some in the other.
class Widget < ActiveRecord::Base
belongs_to :manufacturer
belongs_to :site
end
class Site < ActiveRecord::Base
has_many :widgets
end
class Manufacturer < ActiveRecord::Base
This is bad because Manufacturer.find(1).widgets contains
widgets from both sites
has_many :widgets
I want to do the following instead, but I can’t because
@site is not available to models because it’s a controller
instance variable:
has_many :widgets, :conditions => {:site_id => @site.id}
end
So I have to do things like this instead:
class ManufacturersController < ApplicationController
def show
@manufacturer = Manufacturer.find(params[:id])
@widgets = @manufacturer.widgets.select do |widget|
widget.site == @site
end
end
end
Having to do things like that in almost every action in my controllers
is driving me nuts. It’s horribly un-DRY. I want to take care of the
site filtering at the model level, so my controllers and views don’t
even know the difference.
So the question is, what’s the best-practice for making a variable
available to all models, views, and controllers? A (gasp!) global
variable? This variable needs to be set at the beginning of each
request.
Completely different approaches to solving this problem much appreciated
as well.
Thanks for reading!