2012-07-20 66 views
5

是否有一种方法可以自动使用ActiveRecord :: Base.store存储的类型转换值?ActiveRecord :: Base.store自动类型转换

拿这个完全不切实际例如:

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

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

我知道我可以只重写方法读者年龄将其转换为整数,但我很好奇,如果有这样做的一个未公开的方式。

试图避免这种情况:

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

    def age 
    settings[:age].to_i 
    end 
end 

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

更新

寻找类似:

class User < ActiveRecord::Base 
    store :settings, accessors: {:age => :to_i} 
end 

或者:

class User < ActiveRecord::Base 
    store :settings, accessors: {:age => Integer} 
end 

回答

1

从Rails 3.2.7开始,没有一种方法可以自动输入类型值。我会更新这个问题,如果我曾经遇到过一个办法做到这一点:/

1

我知道两种方式来做到这一点。其中之一,你每次它被转换它。另一个只有在将它保存到数据库时才转换它。

选项之一:定制的setter

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" 

我使用了定制的setter如果我是你。如果你想要一个独立于数据库列(这是一个字符串)的默认值,除了setter之外,还要使用before_save。

+0

感谢您的回复,但这不是我正在寻找的。我希望DSL方法内置了一些内容,可以让我设置默认值。 – 2012-07-21 01:15:03

+0

我认为这是违背了散列点,你可以把任何东西放入...但看看周围n祝你好运 – AJcodez 2012-07-21 02:32:51

+0

同意,这是一个完全滥用ActiveRecord和关系数据库。我猜想这更多是好奇心。 – 2012-07-21 02:54:18

0

最好是连锁,而店里的存取​​方法不是覆盖它们,因为这些神奇的咒语创建的方法是永远不会那么简单,你会认为:

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 

再次,它没有内置的,但它会做的伎俩。它还利用数据库连接适配器从存储在数据库中的字符串转换为您想要的值类型。根据您使用的数据库更改适配器。

0

Storext增加了类型转换和对ActiveRecord::Store.store_accessor顶部其它特征。