Skip to content

Add MealPlan & Meal model #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/models/meal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Meal < ApplicationRecord
belongs_to :meal_plan
belongs_to :recipe
end
24 changes: 24 additions & 0 deletions app/models/meal_plan.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class MealPlan < ApplicationRecord
belongs_to :user
has_many :meals

validates :start_date, presence: true
validates :end_date, presence: true
validates :user, presence: true

def build_meals
user_recipe_ids = user.recipes.pluck(:id)

(start_date..end_date).each do |date|
unused_recipe_ids = user_recipe_ids - meals.map(&:recipe_id)

if unused_recipe_ids.empty?
available_recipe_ids = user_recipe_ids
else
available_recipe_ids = unused_recipe_ids
end

meals.build(date: date, recipe_id: available_recipe_ids.sample)
end
end
end
2 changes: 1 addition & 1 deletion config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module MealPlan
module MealPlanner
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
Expand Down
10 changes: 10 additions & 0 deletions db/migrate/20161205095851_create_meal_plans.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreateMealPlans < ActiveRecord::Migration[5.0]
def change
create_table :meal_plans do |t|
t.date :start_date, null: false
t.date :end_date, null: false
t.references :user, null: false, foreign_key: true
t.timestamps null: false
end
end
end
10 changes: 10 additions & 0 deletions db/migrate/20161205100045_create_meals.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreateMeals < ActiveRecord::Migration[5.0]
def change
create_table :meals do |t|
t.date :date, null: false
t.references :meal_plan, null: false, foreign_key: true
t.references :recipe, null: false, foreign_key: true
t.timestamps null: false
end
end
end
24 changes: 23 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,30 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20161119203421) do
ActiveRecord::Schema.define(version: 20161205100045) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

create_table "meal_plans", force: :cascade do |t|
t.date "start_date", null: false
t.date "end_date", null: false
t.integer "user_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_meal_plans_on_user_id", using: :btree
end

create_table "meals", force: :cascade do |t|
t.date "date", null: false
t.integer "meal_plan_id", null: false
t.integer "recipe_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["meal_plan_id"], name: "index_meals_on_meal_plan_id", using: :btree
t.index ["recipe_id"], name: "index_meals_on_recipe_id", using: :btree
end

create_table "recipes", force: :cascade do |t|
t.string "name", null: false
t.text "description", null: false
Expand All @@ -36,5 +55,8 @@
t.index ["remember_token"], name: "index_users_on_remember_token", using: :btree
end

add_foreign_key "meal_plans", "users"
add_foreign_key "meals", "meal_plans"
add_foreign_key "meals", "recipes"
add_foreign_key "recipes", "users"
end
8 changes: 8 additions & 0 deletions test/factories/meal_plans.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FactoryGirl.define do
factory :meal_plan do
start_date { Date.today }
end_date { 6.days.from_now.to_date }

association(:user)
end
end
5 changes: 5 additions & 0 deletions test/factories/meals.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FactoryGirl.define do
factory :meal do

end
end
64 changes: 64 additions & 0 deletions test/models/meal_plan_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require "test_helper"

describe MealPlan do
describe "validity" do
let(:meal_plan) { MealPlan.new }

before do
meal_plan.valid?
end

it "requires a start date" do
meal_plan.errors[:start_date].must_include "can't be blank"
end

it "requires an end date" do
meal_plan.errors[:end_date].must_include "can't be blank"
end

it "requires a user" do
meal_plan.errors[:user].must_include "can't be blank"
end
end

describe "generating a weekly plan" do
let(:meal_plan) { build(:meal_plan) }

before do
7.times do
create(:recipe, user: meal_plan.user)
end
end

it "populates a meal for each day between the start date and the end date" do
meal_plan.meals.size.must_equal 0

meal_plan.build_meals

meal_plan.meals.size.must_equal 7
end

it "builds valid meals" do
meal_plan.build_meals

meal_plan.meals.all?(&:valid?).must_equal true
end

describe "with more days than recipes" do
let(:meal_plan) { build(:meal_plan, end_date: 8.days.from_now) }

it "build valid meals" do
meal_plan.build_meals

meal_plan.meals.all?(&:valid?).must_equal true
end

it "reuses recipes where necessary" do
meal_plan.build_meals

uniq_ids = meal_plan.meals.map(&:recipe_id).uniq
uniq_ids.size.must_equal 7
end
end
end
end