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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions