RolifyCommunity / rolify

Role management library with resource scoping
https://rolifycommunity.github.io/rolify/
MIT License
3.16k stars 404 forks source link

Support polymorphic relations by using `has_many :through` #571

Open ajclaasen opened 2 years ago

ajclaasen commented 2 years ago

Hello, thanks again for all of your work!

Closes #570

This proposal is a minimal implementation to support polymorphic associations from multiple models that call resourcify, to multiple models that call rolify.

It replaces, in a rudimentary way, the has_and_belongs_to_many into two has_many relations with an explicit join table and passes the :as option to that join table.

I couldn't quite get all of the specs to run after trying for a while, but 49 of them did succeed before the rest failed on database setup. I also could not find the file or spec context for the rolify method, but I would love to spec this feature & help out!

Database setup error log ``` An error occurred while loading ./spec/rolify/config_spec.rb. Failure/Error: create_table(table) do |t| t.string :name t.references :resource, :polymorphic => true t.timestamps end ArgumentError: wrong number of arguments (given 5, expected 1..4) # ./spec/support/schema.rb:5:in `block (2 levels) in ' # ./spec/support/schema.rb:4:in `each' # ./spec/support/schema.rb:4:in `block in ' # ./spec/support/schema.rb:1:in `' # ./spec/support/adapters/active_record.rb:8:in `' # ./spec/spec_helper.rb:21:in `load' # ./spec/spec_helper.rb:21:in `' # ./spec/rolify/config_spec.rb:1:in `require' # ./spec/rolify/config_spec.rb:1:in `' ```

Example polymorphic setup

class User < ApplicationRecord
  rolify role_join_table_name: 'users_roles', as: 'roleable'
end

class Invitation < ApplicationRecord
  rolify role_join_table_name: 'users_roles', as: 'roleable'
end

class UsersRole < ApplicationRecord
  belongs_to :roleable, polymorphic: true
  belongs_to :role
end

Usage

> user.add_role(:admin)
> invitation.add_role(:admin)

> user.has_role?(:admin)
=> true

> invitation.has_role?(:admin)
=> true

> admin_role.users_roles.map(&:roleable)
=> [#<User xxx: "yyy">, #<Invitation xxx: "yyy">]

Please let me know what you think and let me know if there is anything I can do to help!

Other related issues: #318, #411 Related PR: #181

thomas-mcdonald commented 2 years ago

Hi @rjclaasen, this looks good! Need to get the CI working for pull requests in #573 then we can see what's going on

krtschmr commented 1 year ago

rip CI

cedm commented 2 months ago

What's the status on this PR? Has it been superseded by another solution?