ActiveRecord :: Base.store automatic typing

Is there a way to automatically assign values ​​to types that are stored using ActiveRecord :: Base.store?

Take this completely impractical example:

class User < ActiveRecord::Base
  store :settings, accessors: [ :age ]
end

user = User.new(age: '10')
user.age # => '10'

I know that I can just override the reading method for age to convert it to an integer, but I was curious if there is an undocumented way to do this.

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
+5
source share
4 answers

As with Rails 3.2.7, there is no way to automatically get type values. I will update this question if I ever manage to do this: /

+1
source

. , . , .

:

class User < ActiveRecord::Base

  ...

  # public method
  def age=(age)
    self.settings[:age] = age.to_i
  end

  ...

end

:

$ user.age = '12'     # => "12"
$ user.age            # => 12
$ user.age.class      # => Fixnum
$ user = User.new age: '5'
$ user.age.class      # => Fixnum

: before_save ( )

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

$ user = User.new(age: '10')
$ user.save
$ user.age            # => 10
$ user.age.class      # => Fixnum

:

$ user.age = '12'
$ user.age            # => "12"

, . , ( ), before_save .

+1

, , , , , :

define_method(key) do
  send("#{store_attribute}=", {}) unless send(store_attribute).is_a?(Hash)
  send(store_attribute)[key]
end

, , , :

def age_with_typecasting
  ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column.value_to_integer(age_without_typecasting)
end

alias_method_chain :age, :typecasting

Again, it is not built-in, but it will be a trick. It also uses your database connection adapter to convert from a string that is stored in the database to what you want to use the value type. Change the adapter depending on the database you are using.

0
source

Storext adds type casting and other features on top ActiveRecord::Store.store_accessor.

0
source

All Articles