2010-05-17 2 views
19

Rails STI 상황에서 기본 클래스가 인스턴스화 될 때 오류가 발생할 수 있습니까? 재정의 초기화 그것을 할 것입니다하지만 그 다음 하위 클래스에 물방울을 가져옵니다.Rails STI - 기본 클래스 인스턴스화 금지

감사합니다.

답변

0

초기화 기능에서 클래스가 STI 기본 클래스인지 확인하십시오.

왜이 질문을하는 것이 좋을까요? 다른 디자인을 시도하면 더 도움이 될 가능성이 더 높습니다.

-4

기본 클래스에서 self.abstract_class = true을 사용하여 ActiveRecord에 추상 클래스임을 알릴 수 있습니다.

3

이 작업을 시도 할 수 있습니다 :

class BaseClass 
    def initialize 
    raise "BaseClass cannot be initialized" if self.class == BaseClass 
    end 
end 

class ChildClass 
end 

결과가 될 것입니다 : 존 Topley에 의한 대답은 실제로 잘못

+1

BaseClass는 아마도 ActiveRecord :: Base의 자손이므로 initialize는 super를 호출해야합니다. – Douglas

40

하는 데 도움이

a = BaseClass.new # Runtime Error 
b = ChildClass.new # Ok 

희망을. 기본 클래스에서 abstract_class = true로 설정하면 실제로 자식 클래스의 유형 설정이 자동으로 중지됩니다. 게다가, 기본 클래스에서 set_table_name을 제외하고 자식 클래스는 테이블이 존재하지 않는다고 불평 할 것이다.

STI를 사용하지 않을 때 상속을 설정하고 ActiveRecord :: Base 사이의 클래스 계층 구조에서 추상 클래스 (db 테이블에 의해 지원되지 않는 클래스)를 갖고 싶다면, abstract_class = true의 목적은 상속을 설정하기 때문입니다. 및 하나 이상의 모델 클래스를 포함 할 수있다.

raise를 초기화하는 것이 하나의 해결책이며 validates_presence_of : 기본 클래스에 type을 추가하는 것이 해결책입니다. 의 실수로 인스턴스화

class Base 
    private_class_method :new 
end 

이 방법 : 나는 종종 단순히으로 new 클래스 메소드는 비공개로하는 것을 선호

def initialize(*args) 
    raise "Cannot directly instantiate an AbstractUser" if self.class == AbstractUser 
    super 
end 
+0

왜이 답변이 답변의 맨 위에 있지 않습니까? 그것은 0 표를 가진 대답 아래에 앉았고 다른 표는 삭제되었습니다. –

0

:

참고하면 초기화 오버라이드 (override) 할 경우, 당신은 슈퍼 호출 할 필요가 기본 클래스는 오류를 발생 시키지만 기본 클래스에 대한 테스트를 작성하려면 Base.send(:new)으로 인스턴스를 생성 할 수 있습니다.

관련 문제