diff --git a/app/controllers/task_items_controller.rb b/app/controllers/task_items_controller.rb new file mode 100644 index 0000000..9147ead --- /dev/null +++ b/app/controllers/task_items_controller.rb @@ -0,0 +1,46 @@ +class TaskItemsController < ApplicationController + + before_action :ensure_valid_user + before_action :set_task_list + before_action :set_task_item, only: [:update, :destroy] + + def create + @task_item = TaskItem.new(task_item_params) + @task_item.task_list = @task_list + + if @task_item.save + render :show, status: :created, location: @task_item + else + render json: @task_item.errors, status: :unprocessable_entity + end + end + + def update + if @task_item.update(task_item_params) + render :show, status: :ok, location: @task_item + else + render json: @task_item.errors, status: :unprocessable_entity + end + end + + def destroy + @task_item.destroy + head :no_content + end + + private + + def task_item_params + params.require(:task_item).permit(:name, :quantity) + end + + def set_task_list + @task_list = TaskList.find(params[:task_list_id]) + ensure_owner(@task_list) + end + + def set_task_item + @task_item = @task_list.task_items.find(params[:id]) + end + +end \ No newline at end of file diff --git a/app/controllers/task_lists_controller.rb b/app/controllers/task_lists_controller.rb new file mode 100644 index 0000000..696d1dc --- /dev/null +++ b/app/controllers/task_lists_controller.rb @@ -0,0 +1,52 @@ +class TaskListsController < ApplicationController + + before_action :ensure_valid_user + before_action :set_task_list, only: [:show, :update, :destroy] + + def index + @task_lists = TaskList.for_user(current_user) + end + + def show + ensure_owner(@task_list) + end + + def create + @task_list = TaskList.new(task_list_params) + @task_list.user = current_user + + if @task_list.save + render :show, status: :created, location: @task_list + else + render json: @task_list.errors, status: :unprocessable_entity + end + end + + def update + ensure_owner(@task_list) do + if @task_list.update(task_list_params) + render :show, status: :ok, location: @task_list + else + render json: @task_list.errors, status: :unprocessable_entity + end + end + end + + def destroy + ensure_owner(@task_list) do + @task_list.destroy + head :no_content + end + end + + private + + def task_list_params + params.require(:task_list).permit(:name) + end + + def set_task_list + @task_list = TaskList.find(params[:id]) + end + +end \ No newline at end of file diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 8a090fc..8f7065c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,7 +1,5 @@ class UsersController < ApplicationController - UserProxy = Struct.new(:user_id) - before_action :ensure_valid_user, except: [:show, :login, :verify_login, :new, :create] skip_before_action :verify_authenticity_token, only: [:verify_login] diff --git a/app/models/task_item.rb b/app/models/task_item.rb new file mode 100644 index 0000000..8b2c814 --- /dev/null +++ b/app/models/task_item.rb @@ -0,0 +1,7 @@ +class TaskItem < ApplicationRecord + + belongs_to :task_list + + validates :name, presence: true + +end diff --git a/app/models/task_list.rb b/app/models/task_list.rb new file mode 100644 index 0000000..ab29706 --- /dev/null +++ b/app/models/task_list.rb @@ -0,0 +1,12 @@ +class TaskList < ApplicationRecord + + belongs_to :user + has_many :task_items, dependent: :delete_all + + validates :name, + presence: true, + uniqueness: { case_sensitive: false } + + scope :for_user, -> (user) { where(user_id: user) } + +end diff --git a/app/models/user.rb b/app/models/user.rb index ad586c1..4838cd2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,6 +2,7 @@ class User < ApplicationRecord has_many :recipes, dependent: :nullify has_many :ingredients, dependent: :nullify + has_many :task_lists, dependent: :destroy has_secure_password diff --git a/app/views/task_items/_task_item.json.jbuilder b/app/views/task_items/_task_item.json.jbuilder new file mode 100644 index 0000000..eea7dd2 --- /dev/null +++ b/app/views/task_items/_task_item.json.jbuilder @@ -0,0 +1 @@ +json.extract! task_item, :id, :name, :quantity, :created_on, :updated_on \ No newline at end of file diff --git a/app/views/task_lists/_task_list.json.jbuilder b/app/views/task_lists/_task_list.json.jbuilder new file mode 100644 index 0000000..b2b67c8 --- /dev/null +++ b/app/views/task_lists/_task_list.json.jbuilder @@ -0,0 +1,3 @@ + +json.extract! task_list, :id, :name, :created_at, :updated_at +json.task_items task_list.task_items, partial: 'task_item/task_item', as: :task_item diff --git a/app/views/task_lists/index.json.jbuilder b/app/views/task_lists/index.json.jbuilder new file mode 100644 index 0000000..8cd31f6 --- /dev/null +++ b/app/views/task_lists/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @task_lists, partial: 'task_lists/task_list', as: :task_list \ No newline at end of file diff --git a/app/views/task_lists/show.json.jbuilder b/app/views/task_lists/show.json.jbuilder new file mode 100644 index 0000000..4892879 --- /dev/null +++ b/app/views/task_lists/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'task_lists/task_list', task_list: @task_list \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index dcd6d3f..e0f93cc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -33,6 +33,10 @@ Rails.application.routes.draw do end end + resources :task_lists, only: [:index, :show, :create, :update, :destroy] do + resources :task_list_items, only: [:create, :update, :destroy] + end + resource :user, only: [:new, :create, :edit, :update] get '/login' => 'users#login', as: :login diff --git a/db/migrate/20180827214745_create_task_lists.rb b/db/migrate/20180827214745_create_task_lists.rb new file mode 100644 index 0000000..9d61e7d --- /dev/null +++ b/db/migrate/20180827214745_create_task_lists.rb @@ -0,0 +1,10 @@ +class CreateTaskLists < ActiveRecord::Migration[5.2] + def change + create_table :task_lists do |t| + t.integer :user_id, index: true, null: false + t.string :name + + t.timestamps + end + end +end diff --git a/db/migrate/20180827215102_create_task_items.rb b/db/migrate/20180827215102_create_task_items.rb new file mode 100644 index 0000000..3aba437 --- /dev/null +++ b/db/migrate/20180827215102_create_task_items.rb @@ -0,0 +1,11 @@ +class CreateTaskItems < ActiveRecord::Migration[5.2] + def change + create_table :task_items do |t| + t.integer :task_list_id, index: true, null: false + t.string :name + t.string :quantity + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 84ae75c..c5cc620 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2017_04_14_233856) do +ActiveRecord::Schema.define(version: 2018_08_27_215102) do create_table "ingredient_units", force: :cascade do |t| t.integer "ingredient_id", null: false @@ -83,6 +83,7 @@ ActiveRecord::Schema.define(version: 2017_04_14_233856) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.text "preparation" + t.integer "recipe_as_ingredient_id" t.index ["recipe_id"], name: "index_recipe_ingredients_on_recipe_id" end @@ -126,6 +127,23 @@ ActiveRecord::Schema.define(version: 2017_04_14_233856) do t.index ["lowercase_name"], name: "index_tags_on_lowercase_name", unique: true end + create_table "task_items", force: :cascade do |t| + t.integer "task_list_id", null: false + t.string "name" + t.string "quantity" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["task_list_id"], name: "index_task_items_on_task_list_id" + end + + create_table "task_lists", force: :cascade do |t| + t.integer "user_id", null: false + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_task_lists_on_user_id" + end + create_table "usda_food_weights", force: :cascade do |t| t.integer "usda_food_id", null: false t.decimal "amount", precision: 7, scale: 3 diff --git a/spec/controllers/task_list_controller_spec.rb b/spec/controllers/task_list_controller_spec.rb new file mode 100644 index 0000000..4797aec --- /dev/null +++ b/spec/controllers/task_list_controller_spec.rb @@ -0,0 +1,62 @@ +require 'rails_helper' + +RSpec.describe TaskListsController, type: :controller do + + render_views + + before(:each) do + request.accept = "application/json" + end + + let(:user) { + create(:user) + } + + let(:valid_session) { {user_id: user.id} } + + describe 'GET #index' do + it 'assigns all user lists as @task_lists' do + l1 = create(:task_list, user: user) + l2 = create(:task_list, user: user) + create(:task_list) + + get :index, params: {}, session: valid_session + + expect(assigns(:task_lists)).to contain_exactly(l1, l2) + end + end + + describe 'GET #show' do + it 'assigns @task_list' do + l = create(:task_list, user: user) + get :show, params: {id: l.id}, session: valid_session + expect(assigns(:task_list)).to eq l + end + end + + describe 'POST #create' do + it 'creates a task_list' do + expect do + post :create, params: {task_list: {name: 'name'}}, session: valid_session + end.to change(TaskList, :count).by 1 + end + end + + describe 'PATCH #update' do + it 'updates a task_list' do + l = create(:task_list, user: user) + patch :update, params: {id: l.id, task_list: {name: 'new name'}}, session: valid_session + l.reload + expect(l.name).to eq 'new name' + end + end + + describe 'DELETE #destroy' do + it 'destroys the list' do + l = create(:task_list, user: user) + delete :destroy, params: {id: l.id}, session: valid_session + expect(TaskList.where(id: l.id).count).to eq 0 + end + end + +end \ No newline at end of file diff --git a/spec/factories/task_items.rb b/spec/factories/task_items.rb new file mode 100644 index 0000000..1e6dee4 --- /dev/null +++ b/spec/factories/task_items.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :task_item do + task_list + name "MyString" + quantity "MyString" + end +end diff --git a/spec/factories/task_lists.rb b/spec/factories/task_lists.rb new file mode 100644 index 0000000..9f46ca9 --- /dev/null +++ b/spec/factories/task_lists.rb @@ -0,0 +1,11 @@ +FactoryBot.define do + + sequence :generic_task_list_name do |n| + "list_#{n}" + end + + factory :task_list do + user + name { generate(:generic_task_list_name) } + end +end diff --git a/spec/models/task_item_spec.rb b/spec/models/task_item_spec.rb new file mode 100644 index 0000000..691d29e --- /dev/null +++ b/spec/models/task_item_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe TaskItem, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/task_list_spec.rb b/spec/models/task_list_spec.rb new file mode 100644 index 0000000..21e2bf2 --- /dev/null +++ b/spec/models/task_list_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe TaskList, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end