Reputation: 2040
I have a model Item
, which has a relation to itself.
class Item < ActiveRecord::Base
has_many :subitems, :class_name => "Item", :foreign_key => "superitem_id"
belongs_to :superitem, :class_name => "Item"
end
And I want to query all items which have a parent. Firstly I've tried to check if parent_id is present Item.where("superitem_id != ?", false)
, or something like this. But it doesn't work. Although that item has superitem_id, superitem can be already destroyed. So I have to do it with class method
def self.with_superitems
items = []
self.find_each do |i|
items << i if i.superitem
end
return items
end
But it makes chaining impossible, and I want to chain it with similar methods, like
def self.can_be_stored
items = []
self.find_each do |i|
items << i if i.can_be_stored?
end
return items
end
Is it possible to achieve the same results with scopes? Or what would you do?
Upvotes: 1
Views: 311
Reputation: 32933
In rails 2 i would have done this
items = Item.find(:all, :include => [:superitems], :conditions => ["superitems.id is not null"])
the rails3 equivalent of this is
Item.includes([:superitem]).where("superitems.id is not null").all
This way you're pulling in the parent and testing if the id field on the superitem side of the join has an id. if it doesn't, it's because there's no superitem there (or, technically, it could be there but have no id. But this would normally never happen).
Upvotes: 1
Reputation: 9764
I've had a similar issue in the past. It's sometimes difficult to get round it. I found a hack-ish way of doing it for my purposes so hope this will help...
ids = []
self.find_each do |i|
ids << i.id if i.superitem
end
Model.where('id in (?)', ids)
Upvotes: 1
Reputation: 3887
The following will get all the items with a parent, I'm not sure what you mean when you say "Although that item has superitem_id, superitem can be already destroyed"
items = Item.where("superitem_id IS NOT NULL")
Upvotes: 0