Adding multi-tenancy to a Hobo project?

69 views
Skip to first unread message

Michael Q

unread,
Oct 20, 2011, 8:47:56 AM10/20/11
to hobo...@googlegroups.com
Is it possible to add multi-tenancy to a Hobo project?
Is the Hobo user/rights system based on a particular Rails gem?
The built-in system does not seem to cater for multi-tenancy and I'm guessing that trying to implement it in Hobo would cause more trouble that its worth?
Has anyone tried this?

Thanks.

M

Jeremy Savoy

unread,
Oct 20, 2011, 11:33:40 AM10/20/11
to Hobo Users
I am creating a mulit-tenant application myself using Hobo 1.3 ...
here are a few tips ..

1. Set model ownership to each user (do this for each model that will
be owned by each user) by adding this line to each model ...

belongs_to :owner, :class_name => "User", :creator => true

2. Set model permissions appropriately, here is just one example ...

def create_permitted?
owner_is? acting_user
end

3. Define the controller actions to show only the current user's
records, for example if you had a Tasks controller/model ...

auto_actions :all

def index
hobo_index current_user.tasks
end

The Agility tutorial is pretty handy at helping to understand
permissions, but I had to dig around in the group for a bit to find
all of this information and apply it. I still would recommend you take
the time to work through the Agility tutorial if you have not, it
illustrates so many wonderful things about Hobo ...

http://cookbook-1.3.hobocentral.net/tutorials/agility

I hope this helps

Jeremy Savoy

unread,
Oct 20, 2011, 11:42:08 AM10/20/11
to Hobo Users
BTW, there are also the "owner actions" which are hobo automatic
routing actions for owners of records, described here ...

http://cookbook-1.3.hobocentral.net/manual/controllers#owner_actions

However, I found that they didn't work exactly perfect for multi-
tenancy because for the index example it changes your route from ..

/tasks

to

/user/:user_id/tasks

But it doesn't update any of the hobo rapid/dryml generated magic --
so your tab for "Tasks" disappears. There are some older posts where
folks recognized this issue, but I'm not sure if anyone has had time
or desire to investigate how to make these owner actions work better.

Mark Sobkowicz

unread,
Oct 20, 2011, 11:50:36 AM10/20/11
to hobo...@googlegroups.com
In Chad Fowler's new book, Rails Recipes (not the old one of the same name), Recipe 4 is about setting default scopes for models.  I think it would do what you are trying to do really easily.  In your models you say

belongs_to :user
default_scope where(:user => current_user) 

and you don't have to mess with your controllers at all.


Mark

Michael Q

unread,
Oct 20, 2011, 11:52:11 AM10/20/11
to hobo...@googlegroups.com
Thanks Jeremy.

Please forgive me if I'm misunderstanding you, but I'm talking about where a "tenant" is a company, who has several users. So the users must be managed according to the tenant they belong to. Each Tenant gets its own administrator so they can manage their own users etc etc.

Then there is the issue of isolating each Tenant's data. There are a range of solutions to this with various pros & cons. A good compromise is to use Postgres and do schema partitioning. This can be done in plain vanilla Rails, but I was wondering whether anyone has gone this route with Hobo. I'm a beginner and this all seems very daunting. I'd probably have to subcontract this out.

M

Jeremy Savoy

unread,
Oct 20, 2011, 12:15:18 PM10/20/11
to Hobo Users
Mark, I tried your example but got the following ..

undefined local variable or method `current_user'

Mark Sobkowicz

unread,
Oct 20, 2011, 12:20:25 PM10/20/11
to hobo...@googlegroups.com
I always forget that in Hobo its "acting_user" and not "current_user"  in the model.

Mark

Jeremy Savoy

unread,
Oct 20, 2011, 12:21:21 PM10/20/11
to Hobo Users
Michael,

Yes true multi-tenancy would be slightly more complex than multi-user,
but I think it could be accomplished by having a tenant model which
owns an administrator model (in case each tenant may have multiple
admins) which then owns users.

Again I'll refer to the Agility tutorial where you have tasks which
belong to stories which belong to projects, with top down permissions
starting at the projects layer. Think of a similar situation where you
have tasks which belong to users, users who belong to tenant, and
admins who are superusers who belong to tenants with certain
additional permissions.

kevinpfromnm

unread,
Oct 20, 2011, 12:22:10 PM10/20/11
to hobo...@googlegroups.com
While he may have misunderstood, in principle the approach will be similar. 

You'll have a tenant model that each user belongs_to and all items created will be assigned to the tenant of the acting user, likely with an before_create callback.

Probably would be good to pull that out into a module.  See the cookbook source, app/models/owned_model.rb for a good example of how you can get associations and permissions separated out.  Not demonstrated there but you can also define fields and lifecycles within classy modules.

kevinpfromnm

unread,
Oct 20, 2011, 12:24:06 PM10/20/11
to hobo...@googlegroups.com
Unfortunately, acting_user isn't set inside the model as a general rule (just lifecycle transitions/creators and permissions).  You'll still need to modify the controller to have it pass the current_user to the find.

Jeremy Savoy

unread,
Oct 20, 2011, 12:33:49 PM10/20/11
to Hobo Users
One more thing to add, for multi-user ... to the user model ...

has_many :tasks, :class_name => "Task", :foreign_key =>
"owner_id", :dependent => :destroy

Michael Q

unread,
Oct 21, 2011, 3:18:13 AM10/21/11
to hobo...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages