Skip to content

Commit

Permalink
Merge pull request #21 from demesameneshoa/feature/recipe-list
Browse files Browse the repository at this point in the history
Recipes list Issue #7 🎫
  • Loading branch information
demesameneshoa authored Dec 20, 2023
2 parents 67e7fb1 + 495af67 commit 897475c
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 98 deletions.
9 changes: 5 additions & 4 deletions app/controllers/recipes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class RecipesController < ApplicationController

# GET /recipes or /recipes.json
def index
@recipes = Recipe.all
@recipes = Recipe.where(user_id: current_user.id)
end

# GET /recipes/1 or /recipes/1.json
Expand All @@ -20,11 +20,12 @@ def edit; end
# POST /recipes or /recipes.json
def create
@recipe = Recipe.new(recipe_params)

@recipe.user = current_user
respond_to do |format|
if @recipe.save
format.html { redirect_to recipe_url(@recipe), notice: 'Recipe was successfully created.' }
format.json { render :show, status: :created, location: @recipe }
format.html { redirect_to recipes_path, notice: 'Recipe was successfully created.' }
# format.html { redirect_to recipe_url(@recipe), notice: 'Recipe was successfully created.' }
# format.json { render :show, status: :created, location: @recipe }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @recipe.errors, status: :unprocessable_entity }
Expand Down
6 changes: 6 additions & 0 deletions app/models/recipe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@ class Recipe < ApplicationRecord
belongs_to :user
has_many :recipe_foods
has_many :foods, through: :recipe_foods

validates :name, presence: true
validates :preparation_time, presence: true, numericality: { greater_than: 0 }
validates :cooking_time, presence: true, numericality: { greater_than: 0 }
validates :description, presence: true
validates :public, inclusion: { in: [true, false] }
end
2 changes: 1 addition & 1 deletion app/views/foods/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

<div class="field">
<%= form.select :measurement_unit,
options_for_select(["mg", "g", "kg", "l", "ml"]),
options_for_select(["mg", "g", "kg", "l", "ml","units"]),
{ prompt: "Select Measurement Unit" },
aria: { label: "Measurement unit" },
class: "form-control mb-2" %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/_navbar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<%= link_to "My-recipes", root_path, class: "nav-link" %>
</li>
<li class="nav-item">
<%= link_to "Food-List", root_path, class: "nav-link" %>
<%= link_to "Food-List", foods_path, class: "nav-link" %>
</li>
<li class="nav-item">
<%= link_to "Shopping-list", root_path, class: "nav-link" %>
Expand Down
87 changes: 45 additions & 42 deletions app/views/recipes/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,47 +1,50 @@
<%= form_with(model: recipe) do |form| %>
<% if recipe.errors.any? %>
<div style="color: red">
<h2><%= pluralize(recipe.errors.count, "error") %> prohibited this recipe from being saved:</h2>

<ul>
<% recipe.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
<%= form_with(model: recipe) do |form| %>
<% if recipe.errors.any? %>
<div style="color: red">
<h2><%= pluralize(recipe.errors.count, "error") %> prohibited this recipe from being saved:</h2>

<ul>
<% recipe.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="field">
<%= form.text_field :name,
placeholder: "Recipe Name",
aria: { label: "Recipe Name" },
class: "form-control mb-2" %>
</div>
<% end %>

<div>
<%= form.label :name, style: "display: block" %>
<%= form.text_field :name %>
</div>

<div>
<%= form.label :preparation_time, style: "display: block" %>
<%= form.number_field :preparation_time %>
</div>

<div>
<%= form.label :cooking_time, style: "display: block" %>
<%= form.number_field :cooking_time %>
</div>

<div>
<%= form.label :description, style: "display: block" %>
<%= form.text_area :description %>
</div>
<div class="field">
<%= form.text_field :preparation_time,
placeholder: "Preparation Time",
aria: { label: "Preparation Time" },
class: "form-control mb-2" %>
</div>

<div>
<%= form.label :public, style: "display: block" %>
<%= form.check_box :public %>
</div>
<div class="field">
<%= form.text_field :cooking_time,
placeholder: "Cooking Time",
aria: { label: "Cooking Time" },
class: "form-control mb-2" %>
</div>

<div>
<%= form.label :user_id, style: "display: block" %>
<%= form.text_field :user_id %>
</div>
<div class="field">
<%= form.text_area :description,
placeholder: "Description",
aria: { label: "Description" },
class: "form-control mb-2" %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
<div class="custom-control custom-switch">
<%= form.check_box :public, class: "custom-control-input", id:"publicswitch" %>
<label class="custom-control-label" for="publicswitch"> Public: </label>
</div>
</br>
<div class="actions">
<%= form.submit "Save", class: "btn btn-success w-100" %>
</div>
<% end %>
45 changes: 34 additions & 11 deletions app/views/recipes/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
<p style="color: green"><%= notice %></p>
<main class='container mt-4' style="max-width: 900px;">

<h1>Recipes</h1>
<div id="recipes">
<div class="p-2" style="text-align: end;">
<%= link_to "New Recipe", new_recipe_path, class: "btn btn-outline-primary m-1" %>
</div>
<% if @recipes.empty? %>
<div class="alert alert-info text-center">
<p class="mb-0">There are no recipes to show.</p>
</div>
<% else %>

<ul class="list-unstyled pt-4">
<% @recipes.each_with_index do |recipe, index| %>
<li class="text-start d-flex border border-secondary rounded p-2 my-4">
<div class="col-4 ">

<div id="recipes">
<% @recipes.each do |recipe| %>
<%= render recipe %>
<p>
<%= link_to "Show this recipe", recipe %>
</p>
<% end %>
</div>
<div class="col-span-2 my-auto">
<%= link_to recipe_path(id: recipe.id) do %>
<p class="fs-4">Recipe <%= index + 1 %></p>
<% end %>
</div>
<p>Name: <%= recipe.name %></p>
<%= button_to 'Remove', recipe_path(recipe), method: :delete,
class: "btn btn-primary" %>

</div>
<div class="col-8 p-3">
Description: <%= recipe.description %>
</div>
</li>
<% end %>
<% end %>
</ul>
</div>
</main>

<%= link_to "New recipe", new_recipe_path %>
15 changes: 8 additions & 7 deletions app/views/recipes/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<h1>New recipe</h1>
<h1 class="text-muted text-center mb-4">New recipe</h1>
<div style="max-width: 400px; margin: 0 auto;" class="mb-3">
<%= render "form", recipe: @recipe %>

<%= render "form", recipe: @recipe %>
<br>

<br>

<div>
<%= link_to "Back to recipes", recipes_path %>
</div>
<div>
<%= link_to "Back to recipes list", recipes_path, class: "btn btn-secondary px-2 py-1" %>
</div>
</div>
91 changes: 91 additions & 0 deletions spec/controllers/recipes_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
require 'rails_helper'

RSpec.describe RecipesController, type: :controller do
include Devise::Test::ControllerHelpers
let(:user) { create(:user) }
let(:valid_attributes) { attributes_for(:recipe, user:) }
let(:invalid_attributes) { attributes_for(:recipe, name: nil, user:) }

before do
sign_in user
end

describe 'GET #index' do
it 'returns a success response' do
get :index
expect(response).to be_successful
end
end

describe 'GET #show' do
it 'returns a success response' do
recipe = Recipe.create! valid_attributes
get :show, params: { id: recipe.to_param }
expect(response).to be_successful
end
end

describe 'GET #new' do
it 'returns a success response' do
get :new
expect(response).to be_successful
end
end

describe 'POST #create' do
context 'with valid params' do
it 'creates a new Recipe' do
expect do
post :create, params: { recipe: valid_attributes }
end.to change(Recipe, :count).by(1)
end

it 'redirects to the recipes index' do
post :create, params: { recipe: valid_attributes }
expect(response).to redirect_to(recipes_path)
end
end
end

describe 'GET #edit' do
it 'returns a success response' do
recipe = Recipe.create! valid_attributes
get :edit, params: { id: recipe.to_param }
expect(response).to be_successful
end
end

describe 'PUT #update' do
context 'with valid params' do
let(:new_attributes) { { name: 'New Recipe Name' } }

it 'updates the requested recipe' do
recipe = Recipe.create! valid_attributes
put :update, params: { id: recipe.to_param, recipe: new_attributes }
recipe.reload
expect(recipe.name).to eq('New Recipe Name')
end

it 'redirects to the recipe' do
recipe = Recipe.create! valid_attributes
put :update, params: { id: recipe.to_param, recipe: valid_attributes }
expect(response).to redirect_to(recipe_path(recipe))
end
end
end

describe 'DELETE #destroy' do
it 'destroys the requested recipe' do
recipe = Recipe.create! valid_attributes
expect do
delete :destroy, params: { id: recipe.to_param }
end.to change(Recipe, :count).by(-1)
end

it 'redirects to the recipes list' do
recipe = Recipe.create! valid_attributes
delete :destroy, params: { id: recipe.to_param }
expect(response).to redirect_to(recipes_url)
end
end
end
2 changes: 1 addition & 1 deletion spec/factories/recipes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
cooking_time { 1 }
description { 'MyText' }
public { false }
user { nil }
user { create(:user) }
end
end
67 changes: 66 additions & 1 deletion spec/models/recipe_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,70 @@
require 'rails_helper'

RSpec.describe Recipe, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
let(:recipe) { build(:recipe) } # ! non persisting object. It's not saved in the database.

describe 'validations' do
context 'object itself' do
it 'should be valid' do
expect(recipe).to be_valid
end
end

context 'name validations' do
it 'should be valid' do
expect(recipe.name).to be_present
end

it 'should be invalid' do
recipe.name = nil
expect(recipe).to_not be_valid
end
end

context 'preparation_time validations' do
it 'should be valid' do
expect(recipe.preparation_time).to be_present
expect(recipe.preparation_time).to be > 0
end

it 'should be invalid' do
recipe.preparation_time = nil
expect(recipe).to_not be_valid
end
end

context 'cooking_time validations' do
it 'should be valid' do
expect(recipe.cooking_time).to be_present
expect(recipe.cooking_time).to be > 0
end

it 'should be invalid' do
recipe.cooking_time = nil
expect(recipe).to_not be_valid
end
end

context 'description validations' do
it 'should be valid' do
expect(recipe.description).to be_present
end

it 'should be invalid' do
recipe.description = nil
expect(recipe).to_not be_valid
end
end

context 'public validations' do
it 'should be valid' do
expect(recipe.public).to be_in([true, false])
end

it 'should be invalid' do
recipe.public = nil
expect(recipe).to_not be_valid
end
end
end
end
Loading

0 comments on commit 897475c

Please sign in to comment.