From 0f5d105be3497c55f32873d594c42062d3c46a05 Mon Sep 17 00:00:00 2001
From: KaungKaung
Date: Wed, 28 Jan 2026 14:12:24 +0630
Subject: [PATCH] Used Turbo Frames/Streams for adding/deleting tasks without
refresh entire browser
---
app/controllers/tasks_controller.rb | 65 +++++++-------------
app/helpers/tasks_helper.rb | 2 +
app/views/projects/index.html.erb | 3 +
app/views/projects/show.html.erb | 29 +++++----
app/views/tasks/_form.html.erb | 13 ++++
app/views/tasks/create.turbo_stream.erb | 13 ++++
app/views/tasks/destroy.turbo_stream.erb | 1 +
app/views/tasks/new.html.erb | 22 -------
test/controllers/projects_controller_test.rb | 8 +++
test/controllers/tasks_controller_test.rb | 7 +++
10 files changed, 87 insertions(+), 76 deletions(-)
create mode 100644 app/helpers/tasks_helper.rb
create mode 100644 app/views/tasks/_form.html.erb
create mode 100644 app/views/tasks/create.turbo_stream.erb
create mode 100644 app/views/tasks/destroy.turbo_stream.erb
delete mode 100644 app/views/tasks/new.html.erb
create mode 100644 test/controllers/projects_controller_test.rb
create mode 100644 test/controllers/tasks_controller_test.rb
diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb
index 3e56d2d..52b5f46 100644
--- a/app/controllers/tasks_controller.rb
+++ b/app/controllers/tasks_controller.rb
@@ -1,53 +1,34 @@
class TasksController < ApplicationController
- def index
- @project = Project.find(params[:project_id])
- @tasks = @project.tasks
- end
+ before_action :set_project
- def show
- @project = Project.find(params[:project_id])
- @task = @project.tasks.find(params[:id])
- end
+ def create
+ @task = @project.tasks.build(task_params)
- def new
- @project = Project.find(params[:project_id])
- @task = @project.tasks.new
- end
-
- def create
- @project = Project.find(params[:project_id])
- @task = @project.tasks.new(task_params)
- if @task.save
- redirect_to project_task_path(@project, @task)
+ if @task.save
+ respond_to do |format|
+ format.turbo_stream
+ format.html { redirect_to @project, notice: "Task created!" }
+ end
else
- render :new
+ respond_to do |format|
+ format.turbo_stream { render turbo_stream: turbo_stream.replace("new_task", partial: "tasks/form", locals: { project: @project, task: @task }) }
+ format.html { render "projects/show", status: :unprocessable_entity }
end
end
+ end
- def edit
- @project = Project.find(params[:project_id])
- @task = @project.tasks.find(params[:id])
- end
+ def destroy
+ @task = @project.tasks.find(params[:id])
+ @task.destroy
+ end
- def update
- @project = Project.find(params[:project_id])
- @task = @project.tasks.find(params[:id])
- if @task.update(task_params)
- redirect_to project_task_path(@project, @task)
- else
- render :edit
- end
- end
+ private
- def destroy
- @project = Project.find(params[:project_id])
- @task = @project.tasks.find(params[:id])
- @task.destroy
- redirect_to project_tasks_path(@project)
- end
+ def set_project
+ @project = Project.find(params[:project_id])
+ end
- private
- def task_params
- params.require(:task).permit(:title, :description, :status)
- end
+ def task_params
+ params.require(:task).permit(:title, :status)
+ end
end
diff --git a/app/helpers/tasks_helper.rb b/app/helpers/tasks_helper.rb
new file mode 100644
index 0000000..ce894d0
--- /dev/null
+++ b/app/helpers/tasks_helper.rb
@@ -0,0 +1,2 @@
+module TasksHelper
+end
diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb
index 6c15d46..6951f83 100644
--- a/app/views/projects/index.html.erb
+++ b/app/views/projects/index.html.erb
@@ -10,3 +10,6 @@
} %>
<% end %>
+
+
+<%= link_to "Add Project", new_project_path %>
\ No newline at end of file
diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb
index d44d6b8..1583b79 100644
--- a/app/views/projects/show.html.erb
+++ b/app/views/projects/show.html.erb
@@ -1,16 +1,21 @@
<%= @project.project_name %>
<%= @project.description %>
-
-<% @project.tasks.each do |task| %>
- -
- <%= task.title %> (<%= task.status %>)
-
- <%= link_to "Destroy", project_task_path(@project, task), data: {
- turbo_method: :delete,
- turbo_confirm: "Are you sure?"
- } %>
- <% end %>
-
+
+
+ <% @project.tasks.each do |task| %>
+ -
+ <%= task.title %> (<%= task.status %>)
+ <%= link_to "Destroy", project_task_path(@project, task), data: {
+ turbo_method: :delete,
+ turbo_confirm: "Are you sure?"
+ } %>
+
+ <% end %>
+
+
-<%= link_to "Add Task", new_project_task_path(@project) %>
\ No newline at end of file
+
+
+ <%= render partial: "tasks/form", locals: { project: @project, task: Task.new } %>
+
\ No newline at end of file
diff --git a/app/views/tasks/_form.html.erb b/app/views/tasks/_form.html.erb
new file mode 100644
index 0000000..f3c7ef7
--- /dev/null
+++ b/app/views/tasks/_form.html.erb
@@ -0,0 +1,13 @@
+<%= form_with model: [project, task], local: false do |f| %>
+
+ <%= f.label :title %>
+ <%= f.text_field :title %>
+
+
+
+ <%= f.label :status %>
+ <%= f.select :status, Task.statuses.keys %>
+
+
+ <%= f.submit "Create Task" %>
+<% end %>
diff --git a/app/views/tasks/create.turbo_stream.erb b/app/views/tasks/create.turbo_stream.erb
new file mode 100644
index 0000000..24cb5e2
--- /dev/null
+++ b/app/views/tasks/create.turbo_stream.erb
@@ -0,0 +1,13 @@
+<%= turbo_stream.append "tasks_list" do %>
+
+ <%= @task.title %> (<%= @task.status %>)
+ <%= link_to "Destroy", project_task_path(@project, @task), data: {
+ turbo_method: :delete,
+ turbo_confirm: "Are you sure?"
+ } %>
+
+<% end %>
+
+<%= turbo_stream.replace "new_task" do %>
+ <%= render partial: "tasks/form", locals: { project: @project, task: Task.new } %>
+<% end %>
diff --git a/app/views/tasks/destroy.turbo_stream.erb b/app/views/tasks/destroy.turbo_stream.erb
new file mode 100644
index 0000000..84da1cb
--- /dev/null
+++ b/app/views/tasks/destroy.turbo_stream.erb
@@ -0,0 +1 @@
+<%= turbo_stream.remove dom_id(@task) %>
\ No newline at end of file
diff --git a/app/views/tasks/new.html.erb b/app/views/tasks/new.html.erb
deleted file mode 100644
index 890e5bb..0000000
--- a/app/views/tasks/new.html.erb
+++ /dev/null
@@ -1,22 +0,0 @@
-Add new task for "<%= @project.project_name %>"
-
-<%= form_with model: [@project, Task.new], local: true do |task| %>
-
- <%= task.label :title %>
- <%= task.text_field :title %>
- <% @project.tasks.each do |t| %>
- <% t.errors.full_messages_for(:title).each do |message| %>
-
<%= message %>
- <% end %>
- <% end %>
-
-
-
- <%= task.label :status %>
- <%= task.select :status, Task.statuses.keys %>
-
-
-
- <%= task.submit "Create Task" %>
-
-<% end %>
\ No newline at end of file
diff --git a/test/controllers/projects_controller_test.rb b/test/controllers/projects_controller_test.rb
new file mode 100644
index 0000000..4305777
--- /dev/null
+++ b/test/controllers/projects_controller_test.rb
@@ -0,0 +1,8 @@
+require "test_helper"
+
+class ProjectsControllerTest < ActionDispatch::IntegrationTest
+ test "should get index" do
+ get projects_index_url
+ assert_response :success
+ end
+end
diff --git a/test/controllers/tasks_controller_test.rb b/test/controllers/tasks_controller_test.rb
new file mode 100644
index 0000000..a60ed4a
--- /dev/null
+++ b/test/controllers/tasks_controller_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class TasksControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end