Skip to content

Instantly share code, notes, and snippets.

@btc
Created August 7, 2012 19:01
Show Gist options
  • Save btc/3288410 to your computer and use it in GitHub Desktop.
Save btc/3288410 to your computer and use it in GitHub Desktop.
subdomain/locale controller, view issue
=begin
I've run into an architectural challenge. I'm hoping some second opinions will help me organize this logic.
My sites naked and www domains serve as entrypoints to numerous subdomains through which users interact with the site.
=end
models/region.rb
class Region < ActiveRecord::Base
...
end
lib/subdomain.rb
class Subdomain
def self.matches?(request)
request.subdomain.present? && request.subdomain != 'www' &&
Region.active_subdomain?(request.subdomain)
end
end
# I've placed logic about which subdomain a user has visited in a class called Locale.
lib/locale.rb
class Locale
# must provide session and request options
def initialize(options = {})
raise ArgumentError, 'No session provided' if options[:session].nil?
raise ArgumentError, 'No request provided' if options[:request].nil?
@region = case
when Subdomain.matches?(options[:request])
region = Region.find_by_subdomain(options[:request].subdomain)
options[:session][:region_id] = region.id
region # @region = region
else
Region.find_by_id(options[:session][:region_id]) || Region.new
end
end
# return the region object associated with this Locale
def region
@region
end
def valid?
@region.present?
end
end
# Then I place a before_filter in Application controller so Locale gets set up for every request.
class ApplicationController < ActionController::Base
include LocaleHelper
protect_from_forgery
prepend_before_filter :set_locale
helper_method :within_region?
helper_method :initialize_data_for_listings_form
def set_locale
@locale = Locale.new(request: request, session: session)
end
def within_region?
Subdomain.matches?(request)
end
# send return visitors on their way
def redirect_return_visitors
return if @locale.nil? || @locale.valid? == false
r = Region.find_by_id(@locale.region.id)
saved_region = url_for subdomain: r.subdomain,
controller: 'listings', action: 'index'
redirect_to saved_region if return_visitor?
end
def render_404(message = "page not found")
raise ActionController::RoutingError.new(message)
end
def reject_unless_current_user_is_admin
render_404 unless current_user.is_admin?
end
def reject_unless_current_region_set
# TODO to root
redirect_to '/' if @locale.region == nil
end
def initialize_data_for_listings_form(controller)
models = Category.major.sort_by! { |c| c.name }
cvar = :@major_categories
controller.instance_variable_set(cvar, models)
regions = Region.find(@locale.region.id).leaves
regions.sort_by! { |r| r.name }
rvar = :@regions
controller.instance_variable_set(rvar, regions)
end
end
# Here is the locale functionality in use.
# locale in use dot rbs (some html.hamls)
# first:
- if within_region?
= @locale.region.name
# second:
%title= "sitename #{@locale.region.name}"
# third:
#region-step.step
%h1 Where in #{@locale.region.name}?
%hr
= f.association :region, as: :select, label: false,
input_html: { id: 'select-region'},
collection: @regions
%hr
# fourth:
def initialize_data_for_listings_form(controller)
models = Category.major.sort_by! { |c| c.name }
cvar = :@major_categories
controller.instance_variable_set(cvar, models)
regions = Region.find(@locale.region.id).leaves
regions.sort_by! { |r| r.name }
rvar = :@regions
controller.instance_variable_set(rvar, regions)
end
the problem is, the first time someone visits the site, they haven't yet visited a particualr region, so @locale.region is nil. This causes application errors.
I've considered extending application_controller with a module called LocaleHelper to address this.
lib/locale_helper.rb
def current_region_name
if @locale.present? && @locale.region.present?
@locale.region.name
else
''
end
end
def current_region_id
if @locale.present? && @locale.region.present?
@locale.region.id
else
''
end
end
I'm sure there's a better way to accomplish this. Any ideas?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment