2012-07-20 34 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頂部其它特徵。