2011-09-30 4 views
2

다음 모델에서는 상위 작업이 0 개 인 작업 (기본적으로 최상위 작업)을 모두 반환하는 효율적이고 직접적인 방법을 찾고 있습니다. 결국 0 개의 자식 작업과 같은 것을 반환하기를 원할 것입니다. 그래서 일반적인 해결책이 좋을 것입니다. 기존 DataMapper 기능을 사용하여이 작업을 수행 할 수 있습니까? 아니면 수동으로 결과를 필터링 할 수있는 메서드를 정의해야합니까?DataMapper 필터는 연관 수별로 계산합니다.

class Task 
    include DataMapper::Resource 

    property :id, Serial 
    property :name , String, :required => true 

    #Any link of type parent where this task is the target, represents a parent of this task 
    has n, :links_to_parents, 'Task::Link', :child_key => [ :target_id ], :type => 'Parent' 
    #Any link of type parent where this task is the source, represents a child of this task 
    has n, :links_to_children, 'Task::Link', :child_key => [ :source_id ], :type => 'Parent' 

    has n, :parents, self, 
    :through => :links_to_parents, 
    :via => :source 

    has n, :children, self, 
    :through => :links_to_children, 
    :via => :target 

    def add_parent(parent) 
    parents.concat(Array(parent)) 
    save 
    self 
    end 

    def add_child(child) 
    children.concat(Array(child)) 
    save 
    self 
    end 

    class Link 
    include DataMapper::Resource 

    storage_names[:default] = 'task_links' 

    belongs_to :source, 'Task', :key => true 
    belongs_to :target, 'Task', :key => true 
    property :type, String 
    end 

end 
내가 좋아하는 작업 클래스의 공유 방법을 정의 할 수 있도록하고 싶습니다

:

def self.without_parents 
    #Code to return collection here 
end 

감사합니다!

답변

4

DataMapper는 이러한 시나리오에서 실패합니다. 오른쪽에있는 모든 항목이 NULL 인 LEFT JOIN 쿼리가 효율적으로 찾고 있기 때문입니다.

부모와 자녀 상황은 n : n 매핑이기 때문에 차이가 없습니다.

(적어도 버전 1.x) 당신은 혼자가 DataMapper로 얻을 것이다 가장 효율적인은 다음 두 개의 쿼리를 실행합니다

Task.all(:parents => nil) 

. 첫 번째는 n : n 피벗 테이블 (WHERE task_id NOT NULL)에서 상대적으로 간단한 SELECT이고, 두 번째는 첫 번째 쿼리에서 반환 된 모든 ID에 대해 거대한 NOT IN입니다 ... 이는 궁극적으로 찾고있는 것이 아닙니다. 난 당신이 불행하게도 SQL 직접 작성해야 할 것 같아요

)

편집 | https://github.com/datamapper/dm-ar-finders 그리고 find_by_sql 메서드가 중요 할 수 있습니다. 필드 이름 추상화가 중요한 경우 SQL에서 Model.storage_nameModel.some_property.field과 같은 것을 참조 할 수 있습니다.

+0

감사합니다. 그럼에도 불구하고 나는 대답하고 싶지 않다. – Joel