Dealing with deletion, entitlement/roles, and multi-tenancy

Hi,

I am currently avaluating Rails as a possible candidate for replacing
ASP.NET in a core application. I have come across a few issues in my
prototypes which I’d like to solicit the group’s collective wisdom on:

  1. Deletion and selection of database data: Our application does not
    issue delete statements very often; usually it marks a row as deleted
    and then excludes this data by doing conditional selects. The reason
    for this is that customers have this funny habit of deleting things
    they don’t mean to, and this allows us to come back and undelete it
    later.

The problem this poses for me is that I can’t use say
“Organization.departments.each” as-is; I either have to write a select
method which takes deletion into account, or filter the iteration by
each department’s status. The latter is horrid as we do these selcts in
tons of different ways and places. But, the former means I can’t use
the magic association and selection methods in nearly all cases,
because exclusion of deleted-flagged data is something we do throughout
the system.

In practical ue, the application does not select data flagged as
deleted, so I am wondering if there is a way I can instruct the
framework to add “where table.deleted=0” to its constructed SQL. For
the few cases where I do manipulate deleted data, having to write the
SQL manually would be OK.

  1. Multi-tenancy applications: My core application serves many client
    organizations from a single application and database instance. As such,
    models and controllers are constantly checking permissions for who we
    are dealing with. Currently there are no cases in which a session or
    object will access data across multiple organizations. While I can see
    how to implement this in Rails, it looks the same as the way I do it in
    .NET, which is to say I’m still sitting there hooking up lots of
    plumbing in the model. I am wondering if there are any emerging
    patterns or idioms or other things to make this more elegant. I guess
    my perfect world would be one in which the framework understands this
    concept of tenancy more deeply and once I fire up a user session, it
    takes care of deciding what data that user gets. Sorry if the question
    is a little rambling.

  2. User roles, entitlements, and preferences: Our current application
    has a small number of fixed roles, a very-simple entitlement scheme,
    and very few preferences. Customers are kicking down our doors to
    change all three. For instance, Role A should see Field #1, and Role B
    should not. But User X with Role A also has the option to decide
    whether she wants Field 1 displayed on a particular screen or not. So,
    my Views are literally overrun with if-else blocks. I am wondering if
    there are any good examples out there of patterns, idioms, helpers,
    plugins etc for doing this more elegantly.

Probably the biggest mess I have with this problem is tables of data.
ASP.NET promises you nirvana with the DataGrid but then stabs you in
the back when you have large datasets. Rails doesn’t make a promise it
can’t keep which is nicer of it, but it still leaves me hand-coding
lots of paginating sorting and column inclusion/exclusion code and
after a full day of that I want a cigarette, and I don’t smoke.

Anyway, I’ve still enjoyed the framework in many ways- the console and
breakpoint features are great examples of “Duh!” things that make life
so much nicer, and the way you work with SQL databases just makes more
sense than the J2EE/.NET approaches, at least for every application
I’ve worked with where the finer points of distrubuted transactions and
ADO tricks have been unnecessary.

Thanks in advance,
-cwk.

On 11/18/06, CWK [email protected] wrote:

for this is that customers have this funny habit of deleting things
the system.

In practical ue, the application does not select data flagged as
deleted, so I am wondering if there is a way I can instruct the
framework to add “where table.deleted=0” to its constructed SQL. For
the few cases where I do manipulate deleted data, having to write the
SQL manually would be OK.

Check out Rick O.'s excellent plugin acts_as_paranoid. This should
do exactly what you want.

concept of tenancy more deeply and once I fire up a user session, it
takes care of deciding what data that user gets. Sorry if the question
is a little rambling.

There really is not much plumbing needed to handle this sort of thing.
Just use a before_filter in your application.rb to find the current
org.

@current_org = Organization.find_by_id(session[:org:id])

Then scope your queries like this

@files = @current_org.files

  1. User roles, entitlements, and preferences: Our current application
    has a small number of fixed roles, a very-simple entitlement scheme,
    and very few preferences. Customers are kicking down our doors to
    change all three. For instance, Role A should see Field #1, and Role B
    should not. But User X with Role A also has the option to decide
    whether she wants Field 1 displayed on a particular screen or not. So,
    my Views are literally overrun with if-else blocks. I am wondering if
    there are any good examples out there of patterns, idioms, helpers,
    plugins etc for doing this more elegantly.

Use helpers to check field visibility for this logic and functional
tests to validate that each role / preference is rendered correctly.

Probably the biggest mess I have with this problem is tables of data.
ASP.NET promises you nirvana with the DataGrid but then stabs you in
the back when you have large datasets. Rails doesn’t make a promise it
can’t keep which is nicer of it, but it still leaves me hand-coding
lots of paginating sorting and column inclusion/exclusion code and
after a full day of that I want a cigarette, and I don’t smoke.

Pagination is best handled by a case by case basis. The pagination
built into rails will work fine on smaller data sets. Beyond that you
need to figure out what makes sense for your particular solution.

Hope this helps.


Zack C.
http://depixelate.com
http://trackplace.com

On Nov 18, 2006, at 9:38 AM, CWK wrote:

each department’s status. The latter is horrid as we do these
the few cases where I do manipulate deleted data, having to write the
SQL manually would be OK.

Look for acts_as_paranoid. You you can get what you want but think in
terms of real deletion.

patterns or idioms or other things to make this more elegant. I guess
my perfect world would be one in which the framework understands this
concept of tenancy more deeply and once I fire up a user session, it
takes care of deciding what data that user gets. Sorry if the question
is a little rambling.

If you do something like:

@user.tenant.items.find

The SELECT statement will include “items.tenant_id = user.tenenat_id”
automatically.


– Tom M., CTO
– Engine Y., Ruby on Rails Hosting
– Reliability, Ease of Use, Scalability
– (866) 518-YARD (9273)

With associations, you can do stuff like has_many :widgets, :conditions
=> ‘deleted = 0’
and then bob.widgets won’t return any deleted widgets

fred