From ef584747520c97471ef9da4cc91779112f0d5ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=B6hm?= Date: Sun, 28 Jul 2024 18:56:44 +0200 Subject: [PATCH] Scaffold todo model --- app/controllers/todos_controller.rb | 70 +++++++++++++++++++++++ app/helpers/todos_helper.rb | 2 + app/models/todo.rb | 2 + app/views/todos/_form.html.erb | 27 +++++++++ app/views/todos/_todo.html.erb | 12 ++++ app/views/todos/_todo.json.jbuilder | 2 + app/views/todos/edit.html.erb | 8 +++ app/views/todos/index.html.erb | 21 +++++++ app/views/todos/index.json.jbuilder | 1 + app/views/todos/new.html.erb | 7 +++ app/views/todos/show.html.erb | 15 +++++ app/views/todos/show.json.jbuilder | 1 + config/routes.rb | 1 + db/migrate/20240728165519_create_todos.rb | 10 ++++ test/controllers/todos_controller_test.rb | 48 ++++++++++++++++ test/fixtures/todos.yml | 9 +++ test/models/todo_test.rb | 7 +++ test/system/todos_test.rb | 43 ++++++++++++++ 18 files changed, 286 insertions(+) create mode 100644 app/controllers/todos_controller.rb create mode 100644 app/helpers/todos_helper.rb create mode 100644 app/models/todo.rb create mode 100644 app/views/todos/_form.html.erb create mode 100644 app/views/todos/_todo.html.erb create mode 100644 app/views/todos/_todo.json.jbuilder create mode 100644 app/views/todos/edit.html.erb create mode 100644 app/views/todos/index.html.erb create mode 100644 app/views/todos/index.json.jbuilder create mode 100644 app/views/todos/new.html.erb create mode 100644 app/views/todos/show.html.erb create mode 100644 app/views/todos/show.json.jbuilder create mode 100644 db/migrate/20240728165519_create_todos.rb create mode 100644 test/controllers/todos_controller_test.rb create mode 100644 test/fixtures/todos.yml create mode 100644 test/models/todo_test.rb create mode 100644 test/system/todos_test.rb diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb new file mode 100644 index 0000000..5c09d20 --- /dev/null +++ b/app/controllers/todos_controller.rb @@ -0,0 +1,70 @@ +class TodosController < ApplicationController + before_action :set_todo, only: %i[ show edit update destroy ] + + # GET /todos or /todos.json + def index + @todos = Todo.all + end + + # GET /todos/1 or /todos/1.json + def show + end + + # GET /todos/new + def new + @todo = Todo.new + end + + # GET /todos/1/edit + def edit + end + + # POST /todos or /todos.json + def create + @todo = Todo.new(todo_params) + + respond_to do |format| + if @todo.save + format.html { redirect_to todo_url(@todo), notice: "Todo was successfully created." } + format.json { render :show, status: :created, location: @todo } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @todo.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /todos/1 or /todos/1.json + def update + respond_to do |format| + if @todo.update(todo_params) + format.html { redirect_to todo_url(@todo), notice: "Todo was successfully updated." } + format.json { render :show, status: :ok, location: @todo } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @todo.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /todos/1 or /todos/1.json + def destroy + @todo.destroy! + + respond_to do |format| + format.html { redirect_to todos_url, notice: "Todo was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_todo + @todo = Todo.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def todo_params + params.require(:todo).permit(:title, :status) + end +end diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb new file mode 100644 index 0000000..65ab195 --- /dev/null +++ b/app/helpers/todos_helper.rb @@ -0,0 +1,2 @@ +module TodosHelper +end diff --git a/app/models/todo.rb b/app/models/todo.rb new file mode 100644 index 0000000..e7adee6 --- /dev/null +++ b/app/models/todo.rb @@ -0,0 +1,2 @@ +class Todo < ApplicationRecord +end diff --git a/app/views/todos/_form.html.erb b/app/views/todos/_form.html.erb new file mode 100644 index 0000000..324a15c --- /dev/null +++ b/app/views/todos/_form.html.erb @@ -0,0 +1,27 @@ +<%= form_with(model: todo, class: "contents") do |form| %> + <% if todo.errors.any? %> +
+

<%= pluralize(todo.errors.count, "error") %> prohibited this todo from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :title %> + <%= form.text_field :title, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :status %> + <%= form.number_field :status, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %> +
+<% end %> diff --git a/app/views/todos/_todo.html.erb b/app/views/todos/_todo.html.erb new file mode 100644 index 0000000..d78ded5 --- /dev/null +++ b/app/views/todos/_todo.html.erb @@ -0,0 +1,12 @@ +
+

+ Title: + <%= todo.title %> +

+ +

+ Status: + <%= todo.status %> +

+ +
diff --git a/app/views/todos/_todo.json.jbuilder b/app/views/todos/_todo.json.jbuilder new file mode 100644 index 0000000..042f84d --- /dev/null +++ b/app/views/todos/_todo.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! todo, :id, :title, :status, :created_at, :updated_at +json.url todo_url(todo, format: :json) diff --git a/app/views/todos/edit.html.erb b/app/views/todos/edit.html.erb new file mode 100644 index 0000000..91a1744 --- /dev/null +++ b/app/views/todos/edit.html.erb @@ -0,0 +1,8 @@ +
+

Editing todo

+ + <%= render "form", todo: @todo %> + + <%= link_to "Show this todo", @todo, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to todos", todos_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
diff --git a/app/views/todos/index.html.erb b/app/views/todos/index.html.erb new file mode 100644 index 0000000..3e0865a --- /dev/null +++ b/app/views/todos/index.html.erb @@ -0,0 +1,21 @@ +
+ <% if notice.present? %> +

<%= notice %>

+ <% end %> + + <% content_for :title, "Todos" %> + +
+

Todos

+ <%= link_to "New todo", new_todo_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %> +
+ +
+ <% @todos.each do |todo| %> + <%= render todo %> +

+ <%= link_to "Show this todo", todo, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +

+ <% end %> +
+
diff --git a/app/views/todos/index.json.jbuilder b/app/views/todos/index.json.jbuilder new file mode 100644 index 0000000..fc70353 --- /dev/null +++ b/app/views/todos/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @todos, partial: "todos/todo", as: :todo diff --git a/app/views/todos/new.html.erb b/app/views/todos/new.html.erb new file mode 100644 index 0000000..97ec864 --- /dev/null +++ b/app/views/todos/new.html.erb @@ -0,0 +1,7 @@ +
+

New todo

+ + <%= render "form", todo: @todo %> + + <%= link_to "Back to todos", todos_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
diff --git a/app/views/todos/show.html.erb b/app/views/todos/show.html.erb new file mode 100644 index 0000000..f57add9 --- /dev/null +++ b/app/views/todos/show.html.erb @@ -0,0 +1,15 @@ +
+
+ <% if notice.present? %> +

<%= notice %>

+ <% end %> + + <%= render @todo %> + + <%= link_to "Edit this todo", edit_todo_path(@todo), class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to todos", todos_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
+ <%= button_to "Destroy this todo", @todo, method: :delete, class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 font-medium" %> +
+
+
diff --git a/app/views/todos/show.json.jbuilder b/app/views/todos/show.json.jbuilder new file mode 100644 index 0000000..4ab75c3 --- /dev/null +++ b/app/views/todos/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "todos/todo", todo: @todo diff --git a/config/routes.rb b/config/routes.rb index a125ef0..0b2cfec 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :todos # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. diff --git a/db/migrate/20240728165519_create_todos.rb b/db/migrate/20240728165519_create_todos.rb new file mode 100644 index 0000000..9cbcd7c --- /dev/null +++ b/db/migrate/20240728165519_create_todos.rb @@ -0,0 +1,10 @@ +class CreateTodos < ActiveRecord::Migration[7.1] + def change + create_table :todos do |t| + t.string :title + t.integer :status + + t.timestamps + end + end +end diff --git a/test/controllers/todos_controller_test.rb b/test/controllers/todos_controller_test.rb new file mode 100644 index 0000000..a97291e --- /dev/null +++ b/test/controllers/todos_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class TodosControllerTest < ActionDispatch::IntegrationTest + setup do + @todo = todos(:one) + end + + test "should get index" do + get todos_url + assert_response :success + end + + test "should get new" do + get new_todo_url + assert_response :success + end + + test "should create todo" do + assert_difference("Todo.count") do + post todos_url, params: { todo: { status: @todo.status, title: @todo.title } } + end + + assert_redirected_to todo_url(Todo.last) + end + + test "should show todo" do + get todo_url(@todo) + assert_response :success + end + + test "should get edit" do + get edit_todo_url(@todo) + assert_response :success + end + + test "should update todo" do + patch todo_url(@todo), params: { todo: { status: @todo.status, title: @todo.title } } + assert_redirected_to todo_url(@todo) + end + + test "should destroy todo" do + assert_difference("Todo.count", -1) do + delete todo_url(@todo) + end + + assert_redirected_to todos_url + end +end diff --git a/test/fixtures/todos.yml b/test/fixtures/todos.yml new file mode 100644 index 0000000..cc2b225 --- /dev/null +++ b/test/fixtures/todos.yml @@ -0,0 +1,9 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + status: 1 + +two: + title: MyString + status: 1 diff --git a/test/models/todo_test.rb b/test/models/todo_test.rb new file mode 100644 index 0000000..614a849 --- /dev/null +++ b/test/models/todo_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class TodoTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/todos_test.rb b/test/system/todos_test.rb new file mode 100644 index 0000000..45816bd --- /dev/null +++ b/test/system/todos_test.rb @@ -0,0 +1,43 @@ +require "application_system_test_case" + +class TodosTest < ApplicationSystemTestCase + setup do + @todo = todos(:one) + end + + test "visiting the index" do + visit todos_url + assert_selector "h1", text: "Todos" + end + + test "should create todo" do + visit todos_url + click_on "New todo" + + fill_in "Status", with: @todo.status + fill_in "Title", with: @todo.title + click_on "Create Todo" + + assert_text "Todo was successfully created" + click_on "Back" + end + + test "should update Todo" do + visit todo_url(@todo) + click_on "Edit this todo", match: :first + + fill_in "Status", with: @todo.status + fill_in "Title", with: @todo.title + click_on "Update Todo" + + assert_text "Todo was successfully updated" + click_on "Back" + end + + test "should destroy Todo" do + visit todo_url(@todo) + click_on "Destroy this todo", match: :first + + assert_text "Todo was successfully destroyed" + end +end