Last Updated: February 25, 2016
·
2.023K
· EnriqueVidal

HMT associations with acl9

acl9 has been around for a while, but parts of it's code had bothered me for a while specially the use of has_and_belongs_to_many, the problem was that this method did not let you have primary keys in your join table nor timestamps, etc.

Luckily rails 3.0 came out and changed the way associations work, here is how you can override your existing association and create a join model.

First create the following migrations:

class AddMissingFieldsToRolesUsers < ActiveRecord::Migration
  def change
    add_column :roles_users, :created_at, :datetime
    add_column :roles_users, :updated_at, :datetime
    add_column :roles_users, :id,         :primary_key
  end
end

Assuming your join table is named roles_users and that it has no primary key nor timestamps.

class RenameRolesUsersToEnrollments < ActiveRecord::Migration
  def change
    rename_table :roles_users, :enrollments
  end
end

We then rename our join table to enrollments or whatever makes the most sense for you.

We can now create our join model and override acl9 association:

class Enrollment < ActiveRecord::Base
  belongs_to :user
  belongs_to :role

  validates :user, :role, :presence => true
end

class User < ActiveRecord::Base
  acts_as_authorization_subject :association_name => :roles, :join_table_name => :enrollments

  has_many :enrollments
  has_many :roles, :through => :enrollments
end

class Role < ActiveRecord::Base
  acts_as_authorization_role :join_table_name => :enrollments

  has_many :enrollments
  has_many :users, :through => :enrollments
end

And there you have you can now use your join model to navigate either users or roles, you can add new fields to your join table, and add any kind of logic that your join model should need.

If you'd like to see a rails 3.2 application that is already using this checkout https://github.com/rubytij/usergroup the acl9 methods such as has_role?, has_role! and has_no_role! will still work.

3 Responses
Add your response

I wasn't even aware of acl9, thanks for sharing!

over 1 year ago ·

It's been around for a while it has some pretty sweet functionalities.

over 1 year ago ·

This is a great improvement over using DB views. What I missed though was the part about linking objects and subjects without using those views.
I've made an attempt to describe how it should work at http://jimmybonney.com/articles/link_object_subject_acl9_without_database_view/ and I'd be glad to hear your thoughts about it and whether there is another / more efficient way of doing it.

over 1 year ago ·