Hi all, first post here so please be nice
I’m looking for some guidance on how to implement what I am referring to as “virtual associations” into my model in rails.
I’ll preface this with the disclaimer that I have considered going down the real associations path (HABTM) but as far as I can see this would conflict with concepts that I already have implemented.
I currently have a Project
model which can be associated with User
objects via roles
.
As an example, a sample_project
may have many site_managers
, construction_managers
and project_managers
.
A site_manager
can also be a project_manager
for the same or different projects
(rules out single table inheritance).
With the Rolify gem this is fairly straightforward to implement. I can assign any of the roles above to a particular user in a s pecific project with sample_user.add_role(:site_manager, sample_project)
.
One of my goals is to be able to create a form where I can setup a new project, and assign users to roles from using a multi-select list. So as an example, my form would have the following input to assign selected users as site manager for the new project:
= f.input :site_managers, collection: User.all, input_html: { multiple: true }
(Formtastic DSL)
This is where things get slightly complicated. I have managed to implement a custom getter/setter for the site_maanagers
attribute where I can take a hash of user_ids passed by the form and fetch/update the appropriate records as needed.
However this implementation is far from being similar to that of a real association, where I could do things like adding a single user
to the site_managers
with sample_project.site_managers << sample_user
.
At the moment I am also unable to set the array of site_managers using user instances. My custom setter only takes user_ids
as the argument which is a bit cumbersome and not very intuitive when used outside of a form submission implementation. I can easily work around this by checking types inside the setter method but it feel hackery and not very Rails like.
I’ve tried ditching the whole custom getter/setter and going with a HABTM implementation that uses a join table to manage all these records but I am concerned that this won’t scale well if/when we need to add more roles to the project (each role adds an extra column to the join table). It also ends up feeling like I am duplicating functionality/concepts that are already offered with Rolify so in some places I am checking for roles in a join table and in using Rolify in others (i.e. if a user is an admin or has access to a certain resource).
Is there something else I may have overlooked or this the only way of getting this done?
Thanks and I look forward to hearing some of your opinions.
Rog