Subdomains (or second level domains) are still a nice way to present separate interfaces to a single web app — commonly to give a certain kind of customers the feel-n-touch of a dedicated app install.
Here are most of the related aspects based on a particular Rails3 project:
some model
Group, representing a customer, or rather a group of users, has a string columndomain(migration not shown, but don’t forget to index by that column)in
app/models/group.rb:has_many :users before_validation :downcase_domain, :if => :domain_changed? validates :domain, presence: true, uniqueness: true, length: {maximum: 255}, format: /^[0-9a-z-]+$/ def host "#{domain}.#{ROOT_DOMAIN}" end protected def downcase_domain self.domain = domain.to_s.downcase endunder assumption that you’re using
deviseand your (group’s) user identity model isUser(updated for everchangingdevise2.0.4)in
app/models/user.rb:belongs_to :group devise :database_authenticatable, ..., :request_keys => [:app_subdomain] def self.find_for_authentication(conditions={}) group = Group.find_by_domain(conditions.delete(:app_subdomain)) return nil unless group.present? conditions[:group_id] = group.id super endyou’ll have some admin interface where the
groupsare managed (e.g.active_admin, not recommended)in
app/admin/groups.rb:link_to group.domain, root_url(host: group.host)you will certainly want to do something specific in
config/routes.rbyou’ll want some handy helper method, to know which guvnor you’re serving
in
app/controllers/application_controller.rb:helper_method :current_group def current_group return @current_group if defined? @current_group @current_group = request.app_subdomain && Group.find_by_domain(request.app_subdomain) endyou’ll need an initializer of some sort to set a constant and monkey-patch the request class, so…
in
config/initializers/subdomain.rb:ROOT_DOMAIN ||= ENV['ROOT_DOMAIN'] or raise "ROOT_DOMAIN must be set" # (): paranoid monkey patching :() class ActionDispatch::Request def app_subdomain return @app_subdomain if defined? @app_subdomain @@app_hostname_regex ||= /^(?:([0-9a-z-]+).)?#{Regexp.escape(ROOT_DOMAIN)}$/ raise 'Wrong domain' unless host.downcase =~ @@app_hostname_regex @app_subdomain = $1 end endthen, for your production (and staging) environment on, say, heroku, you’ll have to setup your lovely app domain name (with wildcard subdomains) and set the environment variable
ROOT_DOMAINto itfor test environment, which is also good for the handy circleci
in
config/environments/test.rb:ROOT_DOMAIN = 'lvh.me' # yes, it's a magic domain for 127.0.0.1 //smackaho.st RIPfor other environment cases, be sure to set either
ROOT_DOMAINorENV['ROOT_DOMAIN']as appropriateif you use factories (and girls,
factory_girl)in
spec/factories.rb:factory :group do sequence(:domain) {|n| "dom-#{n}"} # or better still, use `forgery` with some smart randomness ... endif you use
capybara(2.0.0 at least, recommended) andrspec(rspec-rails2.12.0 at least)in
spec/spec_helper.rb: (inSpork.preforkblock if you usespork, recommended)Capybara.always_include_port = true # unless you `visit` external sites in your feature specsand then in some
spec/features/..._spec.rb:visit("http://some_domain.#{ROOT_DOMAIN}/some_path") # or visit(some_url host: @group.host) # if you're playing dirty, using pre-fabricated data and route helpers, recommendedin some
spec/controllers/..._spec.rbyou’ll have to include something like this:before(:each) do request.host = @group.host enddon’t forget the specs for domains in
spec/models/group_spec.rband other relevant places
May your sub-domains be obedient to their master.
I have to complete this for a project, simply that! I'm reading right now in the intention of learning from your execution cheap essay writer
ReplyDeletehttps://saglamproxy.com
ReplyDeletemetin2 proxy
proxy satın al
knight online proxy
mobil proxy satın al
ULXZFU
"Mine holds a universe of difficulties and secret treasures. Making the ideal CV can be challenging, much like navigating through a minefield. Hire expert cv writing services to make sure your resume sparkles and aids in landing your ideal job.
ReplyDeleteGood blog postt
ReplyDelete