2011-02-09 9 views
18

więc mam kolumnę zserializowaną: wymiary, aw mojej migracji chciałbym ustawić pole na domyślne hash.domyślne dla kolumny z numerem seryjnym w migracji activerecord

próbowałem ...

create_table :shipping_profiles do |t| 
     t.string  :dimensions_in, :default => {:width => 0, :height => 0, :depth => 0} 

i tylko

t.string :dimensions_in, :default => Hash.new() 

ale pola skończyć null. jak mogę ustawić domyślny serializowany obiekt dla tego pola podczas tworzenia, lub przynajmniej upewnić się, że mój atrybut serialize jest zawsze hash?

Odpowiedz

33

Kiedy Rails szereguje hash do zapisania w db, wszystko, co robi, to przekonwertowanie go na YAML, aby można było zapisać go jako ciąg znaków. Aby uzyskać to do pracy w migracji, wszystko co musisz zrobić, to przekształcić hash YAML ...

t.string :dimensions_in, :default => {:width => 0, :height => 0, :depth => 0}.to_yaml 

albo, alternatywnie, ustawić go w modelu po inicjalizacji ...

class ShippingProfile < ActiveRecord::Base 

    after_initialize :set_default_dimensions 

    private 

    def set_default_dimensions 
     self.dimensions_in ||= {:width => 0, :height => 0, :depth => 0} 
    end 

end 
+0

after_initialize to świetne rozwiązanie! dzięki! – brewster

+3

Dobrze wiedzieć o sztuczce z yaml w migracji, dzięki! – opsb

+0

Świetne odpowiedzi ... – dastanko

4

Próbowałem tego kodu i zadziałało to dla mnie. Wykorzystuje to sposób, w jaki ActiveRecord dynamicznie przesyła metody modeli zsynchronizowane z kolumnami tabeli.

class MyModel < ActiveRecord::Base 

    def dimensions_in 
    attributes["dimensions_in"] ||= {:width => 0, :height => 0, :depth => 0} 
    end 

end 
+0

Świetnie! Może być używana jako wartość domyślna bez określania wartości domyślnej w migracji –

+0

to nie działa z atrybutami, które są serializowane, takie jak 'serialize: dimensions_in, Hash', ponieważ atrybut powraca jako typ obiektu, a zatem jest" obecny ". Będziesz musiał zrobić coś w stylu 'attributes ['dimensions_in']. Present? ? atrybuty ['dimensions_in']: {width: 0, height: 0, depth: 0} ' –

+0

Nadal na Railsach 2;), dziękuję za to – CodeGroover

7

Można również określić domyślną klasę dla kolumny z numerem seryjnym. Zobacz the docs.

class MyModel < ActiveRecord::Base 
    serialize :dimensions_in, Hash 
end 

Znalazłem że after_initialize bloki mogą powodować ogromna wydajność hit, zwłaszcza jeśli będzie kiedykolwiek potrzebne do MyModel.all (np: dla eksportu Bulk)

bez klasy: MyModel.new.dimensions_in => nil

Przy domyślnej klasy Hash: MyModel.new.dimensions_in => {}

+2

Ale jak przekazać wartości domyślne tą metodą? –

+0

@ZuhaibAli Z dokumentów: "domyślną wartością tego atrybutu będzie nowe wystąpienie tej klasy." Dzięki tej metodzie jest to tylko nowa instancja i nie może być czymś niestandardowym. –

Powiązane problemy