Error trying to create roles using rolify gem

170 Views Asked by At

How to use rolify gem? I've not been able to run it in the console to try it out. I followed the documentation. Getting this error from paper trail - ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR: null value in column "item_id" violates not-null constraint) DETAIL: Failing row contains (919, Role, null, create, null, null, 2022-11-25 11:24:25.649806, null, {"id": [null, 1], "name": [null, "admin"], "created_at": [null, ...).. I searched for it and found that some columns might be expecting UUID but getting an ID. My roles table looks like this -

# frozen_string_literal: true

class RolifyCreateRoles < ActiveRecord::Migration[6.1]
  def change
    create_table(:roles) do |t|
      t.string :name
      t.references :resource, type: :uuid, polymorphic: true

      t.timestamps
    end

    create_table(:users_roles, id: false) do |t|
      t.references :user, type: :uuid
      t.references :role
    end

    add_index(:roles, [:name, :resource_type, :resource_id])
    add_index(:users_roles, [:user_id, :role_id])
  end
end

I've spent a lot of time trying to debug it to no avail.

I can do User.first.roles and User.first.has_role?(:admin) but doing User.first.add_role(:admin) gives me the above error from the paper trail gem.

I also tried making the roles tables' ID as UUID but it throws me this error - ActiveRecord::StatementInvalid (PG::UndefinedFunction: ERROR: operator does not exist: uuid = bigint) LINE 1: ... "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_r... ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.

My paper trail table looks like this -

def change
    create_table :versions do |t|
      t.string   :item_type, null: false
      t.uuid     :item_id,   null: false
      t.string   :event,     null: false
      t.string   :whodunnit
      t.text     :object, limit: TEXT_BYTES
      t.datetime :created_at
    end
    add_index :versions, %i[item_type item_id]
  end

I cannot change the item_id type to integer because we already have the whole application using it.

I am using rails 6.1 and ruby 2.7.

1

There are 1 best solutions below

2
max On BEST ANSWER

If you want to use a uuid instead of a bigint for the primary key you need to also set the type for any references to that table:

class RolifyCreateRoles < ActiveRecord::Migration[6.1]
  def change
    create_table(:roles, id: :uuid) do |t|
      t.string :name
      t.references :resource, type: :uuid, polymorphic: true
      t.timestamps
    end

    create_table(:users_roles, id: false) do |t|
      t.references :user, type: :uuid
      t.references :role, type: :uuid # this was missing
    end

    add_index(:roles, [:name, :resource_type, :resource_id])
    add_index(:users_roles, [:user_id, :role_id])
  end
end