Skip to content

Commit 79ef6a6

Browse files
Merge pull request #6 from danieldanilov/allow-editing-existing-learnings
feat: Add edit and update functionality for Learnings
2 parents 4125aad + 6e2a83a commit 79ef6a6

File tree

7 files changed

+112
-38
lines changed

7 files changed

+112
-38
lines changed

app/controllers/learnings_controller.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ def create
2525
end
2626
end
2727

28+
# GET /learnings/1/edit
29+
def edit
30+
@learning = Learning.find(params[:id])
31+
end
32+
33+
# PATCH/PUT /learnings/1
34+
def update
35+
@learning = Learning.find(params[:id])
36+
if @learning.update(learning_params)
37+
redirect_to learnings_path, notice: "Learning updated successfully."
38+
else
39+
render :edit, status: :unprocessable_entity
40+
end
41+
end
42+
2843
def destroy_multiple
2944
learnings_to_delete = Learning.where(id: params[:learning_ids])
3045
deleted_count = learnings_to_delete.count

app/views/learnings/_form.html.erb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<%= form_with(model: learning) do |form| %>
2+
<% if learning.errors.any? %>
3+
<div class="form-errors">
4+
<h2><%= pluralize(learning.errors.count, "error") %> prohibited this learning from being saved:</h2>
5+
<ul>
6+
<% learning.errors.full_messages.each do |message| %>
7+
<li><%= message %></li>
8+
<% end %>
9+
</ul>
10+
</div>
11+
<% end %>
12+
13+
<div>
14+
<%= form.label :title %><br>
15+
<%= form.text_field :title %>
16+
</div>
17+
18+
<div>
19+
<%= form.label :body %><br>
20+
<%= form.text_area :body, rows: 5 %>
21+
</div>
22+
23+
<div>
24+
<%= form.label :learned_on, "Learned On" %><br>
25+
<%# Reason: Use existing date if available (editing), otherwise default to today (new) %>
26+
<%= form.date_field :learned_on, value: (learning.learned_on || Date.today) %>
27+
</div>
28+
29+
<div>
30+
<%= form.label :tags, "Tags (comma-separated)" %><br>
31+
<%= form.text_field :tags %>
32+
</div>
33+
34+
<div>
35+
<%# Reason: Change button text based on whether the record is persisted %>
36+
<%= form.submit (learning.persisted? ? "Update Learning" : "Log Learning") %>
37+
</div>
38+
<% end %>

app/views/learnings/edit.html.erb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<h1>Edit Learning</h1>
2+
3+
<%= render 'form', learning: @learning %>
4+
5+
<%= link_to 'Back to Learnings', learnings_path %>

app/views/learnings/index.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
</div>
5353
<% end %>
5454
<small>Learned on: <%= learning.learned_on.strftime("%B %d, %Y") %></small>
55+
<%# Reason: Add Edit link alongside date %>
56+
<small><%= link_to "Edit", edit_learning_path(learning) %></small>
5557
</div>
5658
</label>
5759
<% end %>

app/views/learnings/new.html.erb

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,3 @@
11
<h1>Log a New Learning</h1>
22

3-
<%= form_with(model: @learning, url: learnings_path, method: :post) do |form| %>
4-
<% if @learning.errors.any? %>
5-
<div class="form-errors">
6-
<h2><%= pluralize(@learning.errors.count, "error") %> prohibited this learning from being saved:</h2>
7-
<ul>
8-
<% @learning.errors.full_messages.each do |message| %>
9-
<li><%= message %></li>
10-
<% end %>
11-
</ul>
12-
</div>
13-
<% end %>
14-
15-
<div>
16-
<%= form.label :title %><br>
17-
<%= form.text_field :title %>
18-
</div>
19-
20-
<div>
21-
<%= form.label :body %><br>
22-
<%= form.text_area :body, rows: 5 %>
23-
</div>
24-
25-
<div>
26-
<%= form.label :learned_on, "Learned On" %><br>
27-
<%= form.date_field :learned_on, value: Date.today %>
28-
</div>
29-
30-
<div>
31-
<%= form.label :tags, "Tags (comma-separated)" %><br>
32-
<%= form.text_field :tags %>
33-
</div>
34-
35-
<div>
36-
<%= form.submit "Log Learning" %>
37-
</div>
38-
<% end %>
3+
<%= render 'form', learning: @learning %>

config/routes.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
get "hire-me", to: "static_pages#hire_me"
1313
get "about", to: "static_pages#about"
1414

15-
# Learning Resources (only index, new, create)
16-
resources :learnings, only: [ :index, :new, :create ] do
15+
# Learning Resources (now including edit/update)
16+
resources :learnings, only: [ :index, :new, :create, :edit, :update ] do
1717
delete :destroy_multiple, on: :collection
1818
end
1919

spec/requests/learnings_spec.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,55 @@
8989
end
9090
end
9191

92+
describe "GET /learnings/:id/edit" do
93+
it "returns http success" do
94+
get edit_learning_path(learning1)
95+
expect(response).to have_http_status(:success)
96+
expect(response.body).to include("Edit Learning")
97+
expect(response.body).to include(learning1.title)
98+
end
99+
end
100+
101+
describe "PATCH /learnings/:id" do
102+
context "with valid parameters" do
103+
let(:new_attributes) {
104+
{ title: "Updated Ruby Basics", body: "Updated body", tags: "ruby, updated", learned_on: Date.today - 3.days }
105+
}
106+
107+
it "updates the requested learning" do
108+
patch learning_path(learning1), params: { learning: new_attributes }
109+
learning1.reload
110+
expect(learning1.title).to eq("Updated Ruby Basics")
111+
expect(learning1.body).to eq("Updated body")
112+
expect(learning1.tags).to eq("ruby, updated")
113+
expect(learning1.learned_on).to eq(Date.today - 3.days)
114+
end
115+
116+
it "redirects to the learnings index" do
117+
patch learning_path(learning1), params: { learning: new_attributes }
118+
expect(response).to redirect_to(learnings_path)
119+
expect(flash[:notice]).to eq("Learning updated successfully.")
120+
end
121+
end
122+
123+
context "with invalid parameters" do
124+
let(:invalid_attributes) { { title: "", body: "" } } # Invalid: missing title and body
125+
126+
it "does not update the learning" do
127+
original_title = learning1.title
128+
patch learning_path(learning1), params: { learning: invalid_attributes }
129+
learning1.reload
130+
expect(learning1.title).to eq(original_title)
131+
end
132+
133+
it "re-renders the 'edit' template" do
134+
patch learning_path(learning1), params: { learning: invalid_attributes }
135+
expect(response).to have_http_status(:unprocessable_entity)
136+
expect(response).to render_template(:edit)
137+
end
138+
end
139+
end
140+
92141
describe "DELETE /learnings/multiple" do
93142
it "deletes the selected learnings" do
94143
learnings_to_delete = [ learning1, learning3 ]

0 commit comments

Comments
 (0)