which way below is more efficient to accomplish this task. I want to loop through a model, check if a list made up of integer vals associated with each model_id is greater than 0. If it is then take the corresponding models into a list of models.
@models = Model.find(:all).collect{|m| m }.reject{ |i| modellist[i.id] < 1 }
or like this
finalModels = []
Model.find_each do |model|
if modellist[model.id] > 0 #edited
#if modellist[model.id] != 0
finalModels.push( model )
end
end
@models = finalModels
Im leaning towards the second approach, but im not sure. Maybe some insight into how .collect and .reject works to see how efficient it is.
My model is called Picture. modellist (or pList) contains data similar to this.
[nil,nil,nil,3,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,
nil,nil,7,nil,nil,nil,0,nil,nil,nil,0,0,nil,nil,1,3]
I the index number of pList corresponds to the picture id for this. So i need to find pics where pList[picture id] is greater than 0.
Used Benoit Garrets answer. What i had to do was make sure that pList was declared by pList = Hash.new and not pList = []. the exact query i used was
@pictures = Picture.find(pList.select {|k, v| v > 0}.keys)
You can just do this in the database directly:
@models = Model.find(:all, :conditions => ["id in (?)", modellist.select{ |i| i && i > 0}])
Or the shorter version:
@models = Model.find(modellist.select{ |i| i && i > 0})
Assuming your modellist
and pList
already exist and are Hash
, you could filter them before and use find
with an array:
@models = Model.find(modellist.reject {|k, v| v < 1} .keys)
Same thing with your second example:
@pictures = Picture.find(pList.reject {|k, v| v > 0} .keys)
This way, you won't be looping over your entire database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With