Как создать цепочечные методы (области) с условиями, не привязанными к базе данных
У меня есть модель Item
, который имеет отношение к себе.
class Item < ActiveRecord::Base
has_many :subitems, :class_name => "Item", :foreign_key => "superitem_id"
belongs_to :superitem, :class_name => "Item"
end
И я хочу запросить все элементы, у которых есть родитель. Во-первых, я попытался проверить, присутствует ли parent_id Item.where("superitem_id != ?", false)
или что-то в этом роде. Но это не работает. Хотя этот элемент имеет superitem_id, superitem уже может быть уничтожен. Так что я должен сделать это с помощью метода класса
def self.with_superitems
items = []
self.find_each do |i|
items << i if i.superitem
end
return items
end
Но это делает цепочку невозможной, и я хочу связать ее с помощью аналогичных методов, таких как
def self.can_be_stored
items = []
self.find_each do |i|
items << i if i.can_be_stored?
end
return items
end
Можно ли добиться таких же результатов с помощью прицелов? Или что бы вы сделали?
3 ответа
У меня была похожая проблема в прошлом. Иногда трудно обойти это. Я нашел хакерский способ сделать это для своих целей, так что надеюсь, что это поможет...
ids = []
self.find_each do |i|
ids << i.id if i.superitem
end
Model.where('id in (?)', ids)
В рельсах 2 я бы сделал это
items = Item.find(:all, :include => [:superitems], :conditions => ["superitems.id is not null"])
rails3 эквивалент этого
Item.includes([:superitem]).where("superitems.id is not null").all
Таким образом, вы вытягиваете родителя и проверяете, есть ли у поля id на стороне суперитема соединения идентификатор. если это не так, то это потому, что там нет суперитема (или, технически, он мог бы быть там, но не иметь идентификатора. Но это обычно никогда бы не произошло).
Следующее получит все элементы с родителем, я не уверен, что вы имеете в виду, когда говорите: "Хотя этот элемент имеет superitem_id, superitem уже может быть уничтожен"
items = Item.where("superitem_id IS NOT NULL")