2011-02-09 2 views
18

그래서 직렬화 된 열이 있습니다. 치수를 마이 그 레이션 할 때 필드를 기본 해시로 설정하고 싶습니다.activerecord 마이그레이션의 직렬화 된 열의 기본값

내가 시도 ...

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

그냥

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

하지만 필드는 널 (null)을 종료합니다. 생성시이 필드에 대한 기본 직렬화 된 객체를 설정하거나 최소한 serialize 속성이 항상 해시인지 확인해야합니까?

답변

33

Rails가 해시를 직렬화하여 데이터베이스에 저장하면 모든 문자열을 YAML로 변환하여 문자열로 저장할 수 있습니다. 이 마이그레이션에서 작동하도록하기 위해, 당신이 할 필요가 ... 대안 초기화 후 모델에서 설정 ... YAML에 해시를 변환

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

또는

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은 훌륭한 솔루션입니다 : 기본 해시 클래스와

! 감사! – brewster

+3

마이 그 레이션에서 yaml 트릭에 대해 잘 아는 것이 대단히 감사합니다! – opsb

+0

좋은 답변 ... – dastanko

4

이 코드를 사용해 본 결과 나에게 도움이되었습니다. 이것은 ActiveRecord가 테이블 컬럼에 동적으로 동기화 된 모델 메소드를 보내는 방식을 이용합니다.

class MyModel < ActiveRecord::Base 

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

end 
+0

좋아요! 마이그레이션시 기본값을 지정하지 않고 기본값으로 사용할 수 있습니다. –

+0

속성이 객체 유형으로 돌아와 "현재"이므로 직렬화 : dimensions_in, Hash와 같은 직렬화 된 속성과 함께 작동하지 않습니다. 'attributes [ 'dimensions_in']. present와 같은 것을 할 필요가있을 것입니다. ? 애트리뷰트 [ 'dimensions_in'] : {width : 0, height : 0, depth : 0}' –

+0

아직 레일 2에 있습니다.)이 덕분에 – CodeGroover

7

또한 직렬화 된 열의 기본 클래스를 지정할 수도 있습니다. the docs을 참조하십시오.

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

나는 당신이 이제까지 MyModel.all에 필요 특히 after_initialize 블록하는 엄청난 성능이 충돌이 발생할 수 있다는 것을 발견했습니다 (예 : 대량 수출) 클래스없이

: MyModel.new.dimensions_in => nilMyModel.new.dimensions_in => {}

+2

이 메서드를 통해 기본값을 전달하는 방법? –

+0

@ZuhaibAli docs에서 : "해당 속성의 기본값은 해당 클래스의 새 인스턴스가됩니다." 따라서이 메소드를 사용하면 새 인스턴스 일 뿐이며 사용자 정의가 될 수 없습니다. –

관련 문제