# frozen_string_literal: true class PermissionsType < ActiveRecord::Type::Value def type :permissions_as_array end def cast(value) result = case value when Array, String, Symbol Permission.calculate(*Array(value)) else value end super(result) end def deserialize(value) named_function = Arel::Nodes::NamedFunction p_table = Permission.arel_table permission_lookup_query = p_table.project(p_table.lower(p_table["name"])) .from(p_table) .where((p_table["value"] & value).eq(p_table["value"])) array_function = named_function.new("array", [permission_lookup_query]) json_function = named_function.new("array_to_json", [array_function]) # SELECT array_to_json( # array( # SELECT LOWER(permissions.name) # FROM permissions # WHERE (roles.permissions_value & permissions.value) = permissions.value) # ) # ) Permission.connection .exec_query("SELECT #{json_function.to_sql}") .cast_values .first .map(&:to_sym) end end