title: Ruby - less expensive way for chained ActiveRecord queries
body: <p>What I have is currently working, but seems to be very expensive, any ideas on making it less expensive would be great!</p>
  
  <p>A <code>User</code> has many <code>Plans</code>, which has many <code>PlanDates</code>. Each <code>PlanDates</code> has a certain recipe denoted by a <code>recipe_id</code> attribute. Each <code>Plan</code> has a <code>meal_type</code> attribute which is either <code>Meat</code>, <code>Vegetarian</code>, or <code>Choice</code>, the latter means mixed. Each <code>Recipe</code> has a <code>type_of_meal</code> attribute that is either <code>Meat</code> or <code>Vegetarian</code>. Each <code>Recipe</code> also has a friendly <code>name</code> attribute.</p>
  
  <p>For a given PlanDate, I need to build an <code>options_for_select</code> in the following format:</p>
  
  <pre><code>[ [recipe_id, "recipe_name"], [recipe_id, "recipe_name"] ... ]
  </code></pre>
  
  <p>The options:</p>
  
  <ul>
  <li>must remove all the <code>recipe_ids</code> that have previously been given to the User (regardless of Plan)</li>
  <li>must remove all the <code>recipe_ids</code> with a type mismatch (i.e., if a Plan has <code>Meat</code> designated, the options must not have any <code>Vegetarian</code> <code>recipe_ids</code>), certainly this is not true if the Plan has <code>Choice</code> designated</li>
  </ul>
  
  <p>Here's the code I currently have:</p>
  
  <pre><code># builds an array of all the recipe_ids that have been given to this User on some PlanDate on some Plan
  recipes_used_before_for_this_user = PlanDate.select { |pd| pd.plan.user.id == user_id }.map { |pd| pd.recipe_id }
  
  # narrows down the world of recipes to those that do NOT have an id of a recipe_used_before_for_this_user
  recipes_not_used_before = Recipe.select { |r| (recipes_used_before_for_this_user.include? r.id) == false }
  
  # going forward, let's assume current_pd = the PlanDate object in question
  
  if current_pd.plan.meal_type == "Choice"
     # easiest: if the meal_type is "Choice" then we just take the recipes_not_used_before and map them into the appropriate format
     recipe_choices_array = recipes_not_used_before.map { |r| [ r.id, r.name ] }
  else
     # if the plan has a "Meat" or "Vegetarian" specification, we need to first narrow the recipes_not_used_before down by the right type and then map into the appropriate format
     recipe_choices_array = recipes_not_used_before.select { |r| r.type_of_meal == potential_pd.first.plan.meal_type }.map { |r| [ r.id, r.name ] }
  end
  </code></pre>
  
  <p>Again, working, but I have a lot of PlanDates and a lot of Recipes, so if there is any way to streamline even further, would love your ideas. Thanks!</p>