Topic: ActiveRecord class find method returning very weird results

I have this problem with one of my controllers that is driving me absolutely bonkers.  On the rendered page, I want to see all ingredients that I have inventory for.  I am getting extraneous ingredients which I should not be seeing, as well as some ingredients that are missing.  I have an Ingredient class, IngredientInventory class, and this code is in the RecipesController:

@all_ingredients = Ingredient.find(:all, :conditions => [ "company_id in (0, ?)", session[:company_id]], :order => "name")
@all_ingredients.each do |ing|
  inventory = IngredientInventory.find(:first, :conditions => [ "ingredient_id = ? and company_id in (0, ?)", ing.id, session[:company_id]])
  @all_ingredients.delete ing if !inventory     
end

I'm using 1.16 with Mongrel, and the queries printed in the log all seem correct.  If I change the find to find_by_sql("select * from ingredients inner join ingredient_inventories on (ingredients.id = ingredient_inventories.ingredient_id), it works.  I have double- and triple-checked the records in the database.

I'm hoping somebody can post some clues, because this is driving me nuts!  I'm thinking AR might be doing something funky behind the scenes, but I don't know what, or how or why...

thanks,
brian

BrewControl.com - Brewery and Brewpub management powered by RoR

Re: ActiveRecord class find method returning very weird results

I think I kinda figured out what was going on.  The results from find(:all) seemed to act like they were immutable.  Can anyone explain this?

BrewControl.com - Brewery and Brewpub management powered by RoR

Re: ActiveRecord class find method returning very weird results

AFAIK, the array is mutable. However, it usually isn't good to remove items in the array while looping through it. Array.reject! is probably better:

@all_ingredients.reject! do |ing|
  ing.ingredient_inventories.find(:first, :conditions => [ "company_id in (0, ?)", session[:company_id]])
end

I'm sure there's a better way to do this all in one SQL query. Maybe this?

@all_ingredients = Ingredient.find(:all, :include => :ingredient_inventories, :conditions => ["ingredient_inventories.id is not null and company_id in (0, ?)", session[:company_id]], :order => "name")

Railscasts - Free Ruby on Rails Screencasts

Re: ActiveRecord class find method returning very weird results

Ryan, you are right.  There is a better way to do it in SQL.  I've been at this about a week, and :include is the thing I wanted to use but had no idea what it was called or where to find it when I needed it.  I've been using the Agile Web Development with Rails book, but haven't read it from front to back.  Array.reject! is interesting as well.
Thanks for the help.  ytmnd, as usual!  smile
BTW, why don't these one-line code snippets view in IE7?!  Annoying...

BrewControl.com - Brewery and Brewpub management powered by RoR

Re: ActiveRecord class find method returning very weird results

bkrahmer wrote:

BTW, why don't these one-line code snippets view in IE7?!  Annoying...

Probably something to do with the CSS. Maybe Vin or Josh can fix it?

Railscasts - Free Ruby on Rails Screencasts