2011-04-12 49 views
0

這裏是我的數據模型:DataMapper的有n個通過和相關查詢

class A 
    has n, :b 
    has n, :c, through => :b 

def active_c 
    c.active 
end 
end 

class C 
    class << self 
    def active 
     all(self.end_on => nil) + all(:conditions => [ "cs.end_on > applied_to" ]) 
    end 
    end 
end 

的SQL後的樣子:

SELECT `cs`.`id` FROM `cs` INNER JOIN `bs` ON `cs`.`id` = `bs`.`c_id` INNER JOIN `as` ON `bs`.`a_id` = `as`.`id` WHERE (`bs`.`a_id` = 1672 AND `cs`.`end_on` IS NULL) 
SELECT `cs`.`id` FROM `cs` INNER JOIN `bs` ON `cs`.`id` = `bs`.`c_id` INNER JOIN `as` ON `bs`.`a_id` = `as`.`id` WHERE (`bs`.`a_id` = 1672 AND (cs > applied_to)) 
SELECT `id`, `created_at`, `updated_at`, `applied_to`, `end_on` FROM `cs` WHERE (1 = 0 OR 1 = 0) GROUP BY `id`, `created_at`, `updated_at`, `applied_to`, `end_on` ORDER BY `id` 

如果我改變active_c這個IMPL:

def active_c 
    C.all(:bs => {:a_id => self.id}).active 
end 

調用a.active_c的結果SQL是:

SELECT `c_id` FROM `bs` WHERE `a_id` = 1670 
SELECT `c_id` FROM `bs` WHERE `a_id` = 1670 
SELECT `id`, `created_at`, `updated_at`, `applied_to`, `end_on` FROM `cs` WHERE ((1 = 0 AND `end_on` IS NULL) OR (1 = 0 AND (cs.end_on > applied_to))) ORDER BY `id` 

現在兩個問題:

  1. 我必須使用cs.end_on在第二個狀態爲表也有一欄叫end_on和DM會混淆
  2. 爲什麼有3個疑問並且其中1 = 0從

感謝

+0

你可以標記與您所使用的語言你的問題? – 2011-04-12 16:53:09

+0

我當然可以。完成。 – yiwen 2011-04-12 17:16:19

回答

1

我試着來設置工作模式,應該在-線W第i個你想達到和這裏有什麼結果:

class A 
    include DataMapper::Resource 

    property :id, Serial 

    has n, :bs 
    has n, :cs, :through => :bs, :via => :c 

    def active_cs 
    cs.active 
    end 
end 

class B 
    include DataMapper::Resource 

    property :id, Serial 

    belongs_to :a 
    belongs_to :c 
end 

class C 
    include DataMapper::Resource 

    property :id, Serial 
    property :end_on, Date 
    property :applied_to, Date 

    has n, :bs 

    def active 
    all(:end_on => nil) + all(:conditions => [ "cs.end_on > applied_to" ]) 
    end 
end 

a = A.create 
b = B.create(:a => a) 
c = C.create(:b => b) 

puts a.active_cs.inspect 

這裏的SQL查詢:

SELECT "id", "end_on", "applied_to" FROM "cs" WHERE ("id" IN (SELECT "cs"."id" FROM "cs" INNER JOIN "bs" ON "cs"."id" = "bs"."c_id" INNER JOIN "as" ON "bs"."a_id" = "as"."id" WHERE ("bs"."a_id" = 1 AND "cs"."end_on" IS NULL)) OR "id" IN (SELECT "cs"."id" FROM "cs" INNER JOIN "bs" ON "cs"."id" = "bs"."c_id" INNER JOIN "as" ON "bs"."a_id" = "as"."id" WHERE ("bs"."a_id" = 1 AND (cs.end_on > applied_to)))) GROUP BY "id", "end_on", "applied_to" ORDER BY "id" 

我不知道如果這正是你所需要的 - 但我希望它能幫助。

這裏有一個工作腳本要點的鏈接:https://gist.github.com/916164

+0

感謝您的回覆和嘗試。但是模型應該是:class B belongs_to c和C有n b – yiwen 2011-04-12 20:57:50

+0

啊,好的!我更新了答案和要點。檢查出 – solnic 2011-04-12 22:34:58

+0

謝謝。我會看到我的代碼有什麼問題 – yiwen 2011-04-13 20:55:14