Skip to content

Commit

Permalink
Edit and update an article
Browse files Browse the repository at this point in the history
Implement the edit and update methods in the ArticlesController to allow
for editing and updating an existing article in the application using
the edit_article_path (articles/:id/edit) and a form in the created
edit.html.erb view file. Refactor the form shared between the new and
edit actions into a partial that both views render.

* Add edit and update actions to ArticlesController
* Add tests for edit and update in ArticlesControllerTest
* Refactor new and edit form into _form.html.erb partial
* Refactor repeated code in ArticlesControllerTest

Completes Rails Getting Started Guide:
* 7 CRUDit Where CRUDit Is Due
  * 7.4 Updating an Article
    * 7.4.1 Using Partials to Share View Code
    * 7.4.2 Finishing Up
  • Loading branch information
msducheminjr committed Dec 28, 2021
1 parent 3d76b4b commit eb49741
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 35 deletions.
14 changes: 14 additions & 0 deletions app/controllers/articles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ def create
end
end

def edit
@article = Article.find(params[:id])
end

def update
@article = Article.find(params[:id])

if @article.update(article_params)
redirect_to @article, notice: "Article was successfully updated."
else
render :edit, status: :unprocessable_entity
end
end

private
def article_params
params.require(:article).permit(:title, :body)
Expand Down
21 changes: 21 additions & 0 deletions app/views/articles/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<%= form_with model: article do |form| %>
<div>
<%= form.label :title %><br>
<%= form.text_field :title %>
<% article.errors.full_messages_for(:title).each do |message| %>
<div class="error"><%= message %></div>
<% end %>
</div>

<div>
<%= form.label :body %><br>
<%= form.text_area :body %><br>
<% article.errors.full_messages_for(:body).each do |message| %>
<div class="error"><%= message %></div>
<% end %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
3 changes: 3 additions & 0 deletions app/views/articles/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h1>Edit Article</h1>

<%= render "form", article: @article %>
22 changes: 1 addition & 21 deletions app/views/articles/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
<h1>New Article</h1>

<%= form_with model: @article do |form| %>
<div>
<%= form.label :title %><br>
<%= form.text_field :title %>
<% @article.errors.full_messages_for(:title).each do |message| %>
<div class="error"><%= message %></div>
<% end %>
</div>

<div>
<%= form.label :body %><br>
<%= form.text_area :body %>
<% @article.errors.full_messages_for(:body).each do |message| %>
<div class="error"><%= message %></div>
<% end %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
<%= render "form", article: @article %>
4 changes: 4 additions & 0 deletions app/views/articles/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<h1><%= @article.title %></h1>

<p><%= @article.body %></p>

<ul>
<li><%= link_to "Edit", edit_article_path(@article) %></li>
</ul>
71 changes: 57 additions & 14 deletions test/controllers/articles_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ def setup
@title_blank = "Title can't be blank"
@body_blank = "Body can't be blank"
@body_short = "Body is too short (minimum is 10 characters)"
@article_title = "Sleepy Time"
@article_body = "I'm asleep: #{'z' * 1000}"
end

test "should get index" do
Expand All @@ -21,6 +23,7 @@ def setup
assert_response :success
assert_select 'h1', @article.title
assert_select 'p', @article.body
assert_select 'a', 'Edit'
end

test "should get new" do
Expand All @@ -32,26 +35,20 @@ def setup
end

test "should create article" do
article_title = "Sleepy Time"
article_body = "I'm asleep: #{'z' * 1000}"

assert_difference("Article.count") do
post articles_url, params: {
article: {
title: article_title,
body: article_body
title: @article_title,
body: @article_body
}
}
end

article = Article.last
assert_redirected_to article_path(article)
assert_equal article_title, article.title
assert_equal article_body, article.body
saved_article_assertions(Article.last)
assert_equal "Article was successfully created.", flash[:notice]
end

test "should display errors if validations fail" do
test "should display errors if create validations fail" do
assert_no_difference("Article.count") do
post articles_url, params: {
article: {
Expand All @@ -62,10 +59,56 @@ def setup
end

assert_select "h1", "New Article"
form_error_assertions
end

test "should get edit" do
get edit_article_url(@article)
assert_response :success
assert_select "h1", "Edit Article"
assert_select "form"
assert_select "div.error", 3
assert_select "div.error", @title_blank
assert_select "div.error", @body_blank
assert_select "div.error", @body_short
assert_select "form div", 3
end

test "should update article" do
patch article_url(@article), params: {
id: @article.id,
article: {
title: @article_title,
body: @article_body
}
}

@article.reload
saved_article_assertions(@article)
assert_equal "Article was successfully updated.", flash[:notice]
end

test "should display errors if update validations fail" do
patch article_url(@article), params: {
id: @article.id,
article: {
title: "",
body: ""
}
}

assert_select "h1", "Edit Article"
form_error_assertions
end

private
def saved_article_assertions(article)
assert_redirected_to article_path(article)
assert_equal @article_title, article.title
assert_equal @article_body, article.body
end

def form_error_assertions
assert_select "form"
assert_select "div.error", 3
assert_select "div.error", @title_blank
assert_select "div.error", @body_blank
assert_select "div.error", @body_short
end
end

0 comments on commit eb49741

Please sign in to comment.