2009-12-31 1 views
2

일부 모델을 설정 중이며 2 개의 기본 기본 클래스를 기반으로합니다 (또는 오히려 클래스였습니다). 등대 페이지에서 공개 된 버그 인 것으로 보이는 My use case에 대해 Datamapper가 STI를 처리하는 데 많은 어려움을 겪은 후에, 대신 모듈을 사용하여 내 모델을 DRY 상태로 유지하도록 모든 등록 정보를 정의하기로 결정했습니다. 불행하게도, 나는 범위 지정 문제를 가지고 있으며, 문제를 더욱 복잡하게 만드는 것은 2 단계의 상속을 사용해야한다는 것입니다.Modama를 사용하여 Datamapper로 등록 정보 정의

module Part 
    def self.included(receiver) 
    receiver.class_eval do 
     include DataMapper::Resource 
     property :id,  Serial 
     #other junk 
    end 
    end 
end 

module HardDrive 
    def self.included(receiver) 
    receiver.class_eval do 
     include Part 
     property :kind,   Enum[:magnetic, :flash] 
     #buncha crap here 
    end 
    end 
end 

class Fujitsu 
    include HardDrive 
    property :rev, String 
end 

내가 오류는 다음과 같습니다 : 여기 손실에있어

uninitialized constant HardDrive::Enum (NameError) 
from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:80:in `const_missing' 
from ./app/models/hard_drive.rb:6:in `included' 
from ./app/models/hard_drive.rb:4:in `class_eval' 
from ./app/models/hard_drive.rb:4:in `included' 
from ./app/models/hard_drives/fujitsu.rb:2:in `include' 
from ./app/models/hard_drives/fujitsu.rb:2 

여기 내 코드입니다. 누구든지이 문제를 어떻게 해결할 수 있었는지, 내가 이것을 할 수있는 더 똑똑한 방법을 알고 있습니까?

답변

2

열거 형은 DataMapper 모듈에서 정의되며 HardDrive 범위로 해결되지 않습니다. (이유를 알고 싶습니까?)

그냥 Enum 대신 DataMapper :: Enum을 넣어 주면됩니다.

더 일반적인 토론에서 이러한 추상화가 정말로 필요한가요? 내가 당신의 코드에서 볼 수있는 한 가지 단점은 로직이 데이터베이스 대신 루비 모듈에 저장되기 때문에 파트와 하드 드라이브에 대해 데이터베이스를 쿼리 할 수 ​​없다는 것입니다.

업데이트

(저자 코멘트 후) 일반적인 대답은 : STI 잊어. ORM은 가지고있는 것이 좋지만, SQL 백엔드 추상화가 가장 좋은 부분입니다. 영구 객체 모델을 가질 수 있다는 인상을 주지만 추상화는 종종 누수되고 STI가 좋은 예입니다. 여기에 대해서는 자세하게 설명하지 않겠지 만 온라인에서 자료를 찾을 수 있습니다. 가장 좋은 점은 one-one, one-many 및 many-many 관계와 같은 SQL 모델링 모범 사례에 충분히 근접해 있어야한다는 것입니다.

다음은 업데이트 된 버전입니다. 나는 그것을 테스트하지 않았으며, 메소드 이름은 아마 잘못,하지만 당신은 아이디어를 얻을 것이다 :

class Part 
    property :serial_number 
    has_one Manufacturer 
end 

class HardDisk 
    property :technology 
    property :platters 
    property :model 
    #... 
    is_one Part 
end 

class Manufacturer 
    property :name #Fujitsu, ... 
    property :website 
    #... 
    has_many HardDisk, [:trough=>Part] 
end 
+0

내가 측정기에 대한 부분 또는 하드 드라이브를 사용하려는 경우에만 것을, 그래서 나는 Part.all을하고 다음 뷰를 렌더링 할 수 그것을 기반으로하지만, 그렇게 큰 손실은 아닙니다. 상속을 사용해 보았지만 루비 상속을 사용할 수없고 서브 클래스에 대해 다른 테이블을 사용하게 할 수는 있습니다. 처음에는 STI로 이것을 디자인했지만, 등대 페이지에는 DM에 알려진 버그가 있습니다. 어떤 전략을 사용 하시겠습니까? – Technocrat