ActiveRecord::Store source code outlines that the most common way enchance getter values is to define methods by hands (you already know that):
All stored values are automatically available through accessors on the
Active Record object, but sometimes you want to specialize this
behavior. This can be done by overwriting the default accessors (using
the same name as the attribute) and calling super to actually
change things.
Your case with question mark methods is a bit simpler though. As long as jsonb keys are basically strings, you could refactor them to have that question mark at the end (and have a corresponding "questioned" getter):
add_column :foos, :roles, :jsonb, null: :false,
default: '{ "bar?" : true, ... }'
class Foo < ActiveRecord::Base
store_accessor :roles, :bar?
Another option, as @Ilya suggested, is to define those methods with some metaprogramming (although it would be tempting to move store_accessor :roles, method inside of the loop just to have all store-related definitions in one place).
And the last, but not the least, is to patch ActiveRecord::Store :) As long as store_accessor is basically just a shortcut which defines getter and setter methods, you could pass it some additional parameter and define questioned? methods based on its value.
Here is an implementation with a separate method to achieve the goal:
module ActiveRecord
module Store
module ClassMethods
def store_accessor_with_question(store_attribute, *keys)
store_accessor(store_attribute, keys)
keys.flatten.each do |key|
define_method("#{key}?") do
send(key) == true
end
end
end
Loading it inside of your config/initializers folder, you should be able to do:
class Foo < ActiveRecord::Base
store_accessor_with_question :roles, :bar, :baz
end
foo = Foo.new
foo.bar #<= true
foo.bar? #<= true