Datamapper имеет сквозной и связанные запросы - PullRequest
0 голосов
/ 12 апреля 2011

Вот моя модель данных:

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 на это значение:

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

Результатом SQL для вызова a.active_c являются:

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 от

Спасибо

1 Ответ

1 голос
/ 12 апреля 2011

Я попытался настроить рабочие модели, которые должны соответствовать тому, чего вы пытаетесь достичь, и вот результат:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...