Is there a way to automatically typecast values that are stored using ActiveRecord::Base.store?
Take this totally impractical example:
class User < ActiveRecord::Base
store :settings, accessors: [ :age ]
end
user = User.new(age: '10')
user.age # => '10'
I know I can just override the reader method for age to convert it to an integer, but I was curious if there was an undocumented way of doing it.
Trying to avoid this:
class User < ActiveRecord::Base
store :settings, accessors: [ :age ]
def age
settings[:age].to_i
end
end
user = User.new(age: '10')
user.age # => 10
Update
Looking for something like:
class User < ActiveRecord::Base
store :settings, accessors: {:age => :to_i}
end
Or:
class User < ActiveRecord::Base
store :settings, accessors: {:age => Integer}
end
As of Rails 3.2.7 there is not a way to automatically typecast values. I'll update this question if I ever come across a way to do it :/
I know of two ways to do it. One of them you convert it every time it is set. The other you convert it only when you save it to the database.
Option one: custom setter
class User < ActiveRecord::Base
...
# public method
def age=(age)
self.settings[:age] = age.to_i
end
...
end
In console:
$ user.age = '12' # => "12"
$ user.age # => 12
$ user.age.class # => Fixnum
$ user = User.new age: '5'
$ user.age.class # => Fixnum
Option two: before_save call (or different before call)
class User < ActiveRecord::Base
before_save :age_to_int
...
private
def age_to_int
# uncomment the if statement to avoid age being set to 0
# if you create a user without an age
self.age = self.age.to_i # if self.age
end
end
In console
$ user = User.new(age: '10')
$ user.save
$ user.age # => 10
$ user.age.class # => Fixnum
Shortcoming of option two:
$ user.age = '12'
$ user.age # => "12"
I'd use the custom setter if I were you. If you want a default value independent of the database column (which is a string), use a before_save in addition to the setter.
Storext adds type-casting and other features on top of ActiveRecord::Store.store_accessor
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With