Skip to content

Support Postgresql json/jsonb columns #875

@23tux

Description

@23tux

I'd love to try for a PR, maybe someone can give me some guidance where to start:

We have a table with a jsonb column, that has a GIN index on it and stores various information. I'd like to define abilities based on fields inside that jsonb column.

How would one implement such a feature in cancancan? I know that I can pass scopes to abilities, but that doesn't solve calls like can?(:index, product) and they are not mergeable. So supporting jsonb columns the same way normale columns are supported would be awesome.

This gist should describe what I want to achieve:

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"
  gem "rails", "= 7.1.5.1"
  gem "cancancan", "= 3.6.1", require: false # require false to force rails to be required first
end

require "active_record"
require "cancancan"
require "minitest/autorun"
require "logger"

ActiveRecord::Base.establish_connection(
  adapter: "postgresql",
  database: "test",
  username: "postgres",
  password: "password",
  host: "localhost"
)
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  drop_table :products, if_exists: true
  create_table :products, force: true do |t|
    t.jsonb :data
  end
end

class Product < ActiveRecord::Base; end

class Ability
  include CanCan::Ability

  def initialize
    can :index, Product, data: { shop_id: 1 }
  end
end

class BugTest < Minitest::Test
  def test_bug
    product = Product.create!(data: { shop_id: 1 })
    ability = Ability.new
    assert_equal [product], Product.accessible_by(ability, :index).to_a
  end
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions