I am using a standard rails form to update an ActiveRecord::Store
store :settings, accessors: %i[is_public]
My form looks like this:
<%= form.select(:is_public, options_for_select([['True', true], ['False', false]])) %>
When I look at the saved hash these have been converted to strings, is there a way to preserve the boolean type here?
CodePudding user response:
I was able to write a CustomStoreAccessor module to overwrite the accessor for these attributes:
module CustomStoreAccessor
def boolean_store_accessor(attr_name)
define_method "#{attr_name}=" do |value|
super(value=='true')
end
define_method attr_name do
super()=='true'
end
end
def integer_store_accessor(attr_name)
define_method "#{attr_name}=" do |value|
super(value.to_i)
end
define_method attr_name do
super().to_i
end
end
end
This then allows me to add these methods to my model:
class Client < ApplicationRecord
extend CustomStoreAccessor
store :settings_object, accessors: %i[is_public max_sessions]
boolean_store_accessor :is_public
integer_store_accessor :max_sessions
CodePudding user response:
Do not use store
. It has no place at all except in legacy applications.
Storing serialized data in a varchar/text column is a completely outdated approach since you database almost certainly has a native JSON/JSONB type - which actually can be queried efficiently whereas serialized data is either non-querable if its marshalled Ruby or YAML or requires you to de-serialize the data at query time if it happens to be stored as a JSON string.
The database driver will also automatically serialize/deserialize the column. Using store
or its cousin serialize
will actually "double convert" it so you end up with JSON strings instead of actual meaningful types such as objects and arrays.
If you want to create accessors for "attributes" in a JSON object use store_accessor
.