Last active
November 2, 2022 13:02
-
-
Save ozgun/e062ff629708286f7211 to your computer and use it in GitHub Desktop.
Using ActiveRecord::Store to store boolean fields
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# File: app/models/concerns/boolean_store_accessor.rb | |
# | |
# When we submit a form in order to update a model, a booelan/checkbox field is posted | |
# as '1' or '0', and if we are using ActiveRecord::Store, posted value is stored in | |
# database as '1' or '0'. By the help of this module, we store '1' and '0' | |
# values as `true` or `false`. | |
# | |
# Example usage: | |
# | |
# ``` | |
# class Page < ActiveRecord::Base | |
# extend BooleanStoreAccessor | |
# store :settings, accessors: [:hide_from_navigation] | |
# boolean_store_accessor :hide_from_navigation | |
# end | |
# | |
# page = Page.first | |
# page.hide_from_navigation? #=> false | |
# page.hide_from_navigation = true | |
# page.save | |
# page.hide_from_navigation? #=> true | |
# page.settings #=> {"hide_from_navigation"=>true} | |
# ``` | |
# | |
module BooleanStoreAccessor | |
def boolean_store_accessor(attr_name) | |
define_method "#{attr_name}=".to_sym do |value| | |
values = ['1', true] | |
super((values.include?(value)) ? true : false) | |
end | |
define_method attr_name do | |
values = [nil, false, '0'] | |
(values.include?(super())) ? false : true | |
end | |
define_method "#{attr_name}?".to_sym do | |
send(attr_name) | |
end | |
end | |
end |
Thanks for this!
Thanks for this!
My pleasure :)
Thanks for this! Here's a small change that allows defining a series of multiple attributes in the same signature as store_accessor
.
boolean_store_accessor :eula_agreement, :subscribe
module BooleanStoreAccessor
def boolean_store_accessor(*attr_names)
attr_names.each do |attr_name|
define_method "#{attr_name}=".to_sym do |value|
values = ['1', true]
new_value = values.include?(value) ? true : false
begin
super(new_value)
rescue NoMethodError => e # This is hack for `attr_accessor`
if e.message.match?(/super: no superclass method/)
instance_variable_set("@#{attr_name}", new_value)
else
raise e
end
end
end
define_method attr_name do
values = [nil, false, '0']
stored_value =
begin
super()
rescue NoMethodError => e # This is hack for `attr_accessor`
if e.message.match?(/super: no superclass method/)
instance_variable_get("@#{attr_name}")
else
raise e
end
end
(values.include?(stored_value)) ? false : true
end
define_method "#{attr_name}?".to_sym do
send(attr_name)
end
end
end
end
Thanks @dylanfisher . I haven't tested it yet but it looks good to me at first glance. 👍
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@esale great, thanks!