Datamapper «первый» метод запрашивает всю связь - PullRequest
2 голосов
/ 25 июля 2010

Я использую Datamapper 1.0 с sinatra и sqlite3 в качестве бэкэнда.

У меня есть несколько устройств с несколькими местоположениями, и я обычно хочу только самое последнее местоположение устройства. Проблема в том, что сгенерированный SQL для вышеуказанной строки будет запрашивать все местоположения устройства, а не только самое последнее (и устройство может иметь 10-20 тыс. Местоположений). Это явно не оптимально, поэтому я спрашиваю: я что-то не так делаю? Или datamapper работает таким образом, и я должен вернуться к простому SQL? Есть ли лучший обходной путь?

У меня есть следующая схема данных:

class Location
  include DataMapper::Resource
  property :id, Serial
  property :lat, Integer
  property :lon, Integer
  property :time, Time
  belongs_to :device
end

class Device
  include DataMapper::Resource
  property :id, Serial
  has n, :locations

  def lat # and lon
    locations.first(:order => [:time.desc]).lat
  end
end 

Здесь вызов d.first.lat (где d - это Device, полученный с использованием d = Devices.all) приведет к запросу всех местоположений, а не только к первому соответствующему.

У меня есть только эти две модели, и запросы тоже просты:

  • В контроллере: @devices = Device.all
  • В поле зрения: @devices.each { |d| d.lat }
  • А в модели: def lat; locations.first.lat; end

Спасибо.

1 Ответ

1 голос
/ 29 декабря 2010

Я думаю, уловка состоит в том, чтобы иметь 1 ассоциацию

class Device
  include DataMapper::Resource
  property :id, Serial
  has n, :locations # You probably want :order => [:time.desc] here too
  has 1, :latest_location, :class_name => Location, :order => [:time.desc]

  def lat
    latest_location.lat
  end
end
...