Как всегда использовать базовый класс и игнорировать STI в Rails? - PullRequest
6 голосов
/ 11 февраля 2012

У меня есть модуль, который я включаю в несколько моделей с таким содержимым:

self.class.find_by_foo(bar)

Все было хорошо, пока я не начал использовать STI.Эта строка всегда должна генерировать запрос

select * from table where foo=bar"

и , а не

select * from table where foo=bar AND type="Whatever"

Есть ли простой способ избежать этого?

Хотя яиз двух решений.Прогуливаясь по иерархии классов, пока не найду самый верхний класс до ActiveRecord::Base или не выполню запрос вручную, например:

self.class.find_by_sql("select * from #{self.class.table_name} where foo=bar")

Мне не нравится ни одно из решений.Есть ли лучший?

Ответы [ 2 ]

23 голосов
/ 17 октября 2012

Во-первых, вы всегда можете добраться до базового класса с помощью метода base_class:

self.class.base_class.find_by_foo(bar)

Однако в приведенном выше примере вам не нужно иметь доступ к базовому классу.Вы можете просто сделать следующее, и Rails узнает правильное имя таблицы:

self.class.where(:foo => bar)

На самом деле очень мало случаев, когда вам нужен доступ к базовому классу.

2 голосов
/ 11 февраля 2012

Пока нет лучшего ответа, я использую этот код, чтобы найти базовый класс цепочки ИППП:

klass = self.class
self.class.ancestors.each do |k|
  if k == ActiveRecord::Base
    break # we reached the bottom of this barrel
  end
  if k.is_a? Class
    klass = k
  end
end
...