MultiSite provides the ability to scope your models by tenant. MultiSite gem is very similar to multi-tenancy gems such as acts_as_tenant but less strict on it's implementation.
If you need to organize your models by site scope MultiSite is great for that!
gem'multi_site'- provides scopes to fetch records from a specific site
- give you helper methods know what is the current site
- keeps the switch site logic away from your application.
First, you need to have a class named Site. This is the only constraint you have.
classSite < ActiveRecord::Base# ...endIn your Models you need to insert the class method has_site_scope to declare which ones
are scoped by site:
classUser < ActiveRecord::Basehas_site_scopeendclassCard < ActiveRecord::Basehas_site_scopeendNow on, every model registered has a new scope called on_site.
When you call the model User with scope on_site it should return all the users
from current site:
classUsersController < ApplicationControllerdefindex#fetch all the users@all_users=User.all#fetch all the users from current site@site_users=User.on_site#fetch all the users from current site with a certain age@site_users=User.on_site.where(:age=>15)endendInstead of scoping the classes to their tenants by default, MultiSite, allows the programmer to choose what he wants.
MultiSite provides a routing helper to to hide the site handling from you.
Application.routes.drawdomulti_site_scopedoresources:users# this will handle a uri like this:# /:multi_site/users/:id# and you can use the route helpers transparently# e.g. new_user_url, edit_user_path(1), etcresources:cards# /:multi_site/cards/...endendAll the resources inside of multi_site scope will automatically handle the multi_site
parameter, and all route helpers will use it transparently.
MultiSite provides a helper method called current_site. It can be used on views or controllers
context and give us the current site selected by the application.
<% if current_site.present? %><p>Site Name: <%=current_site.name%></p><%else%><p> Please you need to <%=link_to"login","/login"%> first.
<%end%>MultiSite doesn't provide any security features. You have the responsability to implement them. For example, to guarantee that a user doesn't have access to unauthorized tenants, you can create a before_filter action that checks if the user's site is the same as current_site:
classUsersController < ApplicationControllerbefore_filter:check_site_access#...defcheck_site_accessunlesscurrent_user.site == current_siteraise"Access Denied"endendendYou'll surely need cross site operations. We can get you there providing a macro that allows site switching:
classAdmin::AdminController < ApplicationControllercross_site_controllerdefshow@admin_site=current_siteenddefswitch_siteself.current_site=Site.find(params[:site_id])redirect_toadmin_admin_url,notice: "Switched to: #{current_site.url}"endendyou can declare the default site with:
MultiSite::Supra.default_site=Site.where(default: true).firstMultiSite uses thread context to keep current site id saved for scopes. If you initializate new threads you need to copy the current site to the new thread in order to keep the functionality unchanged.
For example:
site=current_siteThread.new{MultiSite.current_site=site# .. do you work hereusers=User.on_siteusers.map{|u| u.simulate_taxes}}- make the site model name customizable
- make the param name entry customizable
- add specs for Rails 3+. Only Rails 4+ are provided at the moment
Copyright © 2013 Runtime Revolution, released under the MIT license.
