루비 온 레일즈 v5.2 시작하기

2020. 7. 1. 10:04위키

루비 온 레일즈 v5.2 에 대한 시작하기 가이드입니다. 간단한 블로그 어플리케이션을 만들어보면서 레일즈에 대해 배웁니다. Rails Guide를 참고했습니다. 개발환경과 코드에 대해서는 아래를 참고하시기 바랍니다.

macOS Catalina
ruby 2.6.6
rails 5.2.3
 

hwangwoojin/rails-blog

This is my code from getting_started guide at RailsGuides v5.2 : https://guides.rubyonrails.org/v5.2/getting_started.html - hwangwoojin/rails-blog

github.com

 

blog 어플리케이션 시작하기

먼저 blog 어플리케이션을 새로 생성하겠습니다.

$ rails new blog
# 만약 WSL 에서 사용할 경우 --skip-spring --skip-listen 옵션 추가해서 해보기

그러면 blog 라는 이름의 폴더가 생성됩니다. 해당 폴더로 이동합니다.

$ cd blog

잘 생성되었는지 확인하기 위해 웹서버를 켜서 접속해보도록 하겠습니다.

$ bin/rails server
# 윈도우일 경우 bin/rails 가 안된다면 bin\rails 로 한번 해보세요

웹서버가 성공적으로 시작했다면 http://localhost:3000/ 에 접속했을 때 다음과 같은 화면을 볼 수 있습니다.

 

지금은 2.6.5 에서 업데이트해서 2.6.6 씁니다.

 

Hello, World! 띄우기

간단한 Hello, World! 화면을 띄우기 위해서 Ruby on Rails 에서는 컨트롤러와 뷰가 필요합니다. 먼저 컨트롤러를 생성하겠습니다. 다음 코드는 Welcome 이라는 이름과 index 라는 액션을 가진 컨트롤러를 생성합니다.

$ bin/rails generate controller Welcome index

그러면 여러 파일들이 추가됩니다. 이 파일들에 대해서는 이후에 다루어보도록 하겠습니다. 먼저 사용자가 볼 index.html 파일을 생성해야 합니다. 이때 사용하는 파일 형식은 embeded ruby 를 줄인 erb 입니다.

<!-- app/views/welcome/index.html.erb -->

<!-- 기존의 코드
<h1>Welcome#index</h1>
<p>Find me in app/views/welcome/index.html.erb</p>
-->

<h1>Hello, World!</h1>

기존의 코드는 깔끔하게 주석처리해버리고 새로 <h1>Hello, World!</h1> 를 추가했습니다. 그러면 http://localhost:3000/welcome/index 에 접속했을때 Hello, World! 가 나타납니다.

 

안녕, 세계!

 

하지만 아직 http://localhost:3000/ 는 그대로인 상태입니다. 이를 변경하기 위해서는 routes.rb 파일에 root 를 추가해주어야 합니다.

# config/routes.rb

Rails.application.routes.draw do
  get 'welcome/index'

  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html

  root 'welcome#index' # 새로 추가한 코드
end

그러면 이제 http://localhost:3000/ 를 접속했을 때도 Hello, World! 를 볼 수 있습니다.

 

Articles 만들기 (create)

Hello, World! 라는 한 문장을 보여주는 것을 blog 라고 부르지는 않죠. 보통 블로그에는 글(Articles) 이 존재합니다. 이번에는 이 Article 을 만들어보도록 하겠습니다.

 

Articles 은 하나의 리소스입니다. 리소스라는건 만들고, 읽고, 쓰고 삭제할 수 있는 데이터라는 것이죠. 이를 다른말로 CRUD 할 수 있다고도 합니다. 각각 create, read, update, delete 를 말합니다. Ruby on Rails 는 매우 RESTful 하기 때문에 다음과 같이 routes 에 resources 를 선언하면 됩니다.

# config/routes.rb

Rails.application.routes.draw do
  get 'welcome/index'

  resources :articles # 새로 추가한 코드

  root 'welcome#index'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

Articles 을 위한 컨트롤러도 생성해줍니다. 그러면 또 이것저것 생성이 됩니다.

$ bin/rails generate controller Articles

 Articles 를 위한 메서드는 articles_controller.rb 에 정의되어 있습니다. 처음에는 아무것도 없습니다. 여기에 새로 new 라는 메서드를 선언하도록 하겠습니다.

# app/controllers/articles_controller.rb

class ArticlesController < ApplicationController
    # 새로 추가한 메서드
    def new
    end
end

뷰도 만들어줍니다.

<!-- app/views/articles/new.html -->

<h1>New Article</h1>

그러면 http://localhost:3000/articles/new 에 접속했을 때 New Article 이 정상적으로 나타납니다.

 

 

Ruby on Rails 는 form 이란 것을 지원합니다. 이것은 form_with 라는 것을 통해 페이지를 아주 쉽게쉽게 만들 수 있는 일종의 템플릿같은 개념입니다. 아까 new.html 을 만든 같은 위치에 new.html.erb 파일을 생성하고 다음 코드를 입력합니다.

<!-- app/views/articles/new.html.erb -->

<%= form_with scope: :article, url: articles_path, local: true do |form| %>
  <p>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </p>
 
  <p>
    <%= form.label :text %><br>
    <%= form.text_area :text %>
  </p>
 
  <p>
    <%= form.submit %>
  </p>
<% end %>

그러면 다음과 같은 페이지가 짠 하고 나타납니다.

 

 

하지만 아직 Save Article 버튼은 제대로 동작하지 않습니다. 이를 제대로 동작시키기 위해서는 create 메서드를 만들어주어야 합니다. 다음과 같이 만들어주도록 하겠습니다.

# app/controllers/articles_controller.rb 에 메서드 추가


def create
    @article = Article.new(params.require(:article).permit(:title, :text))
        
    @article.save # article 이 저장되었는지에 대한 boolean 값
    redirect_to @article
end

이 코드는 article 의 정보를 Article 이라는 클래스에 저장하는 코드입니다. 여기서 눈여겨보아야 할 점은 permit 입니다. Ruby on Rails 에서는 데이터를 전달할 때 모든 파라미터를 동시에 전달하는 것을 막습니다. 왜냐하면 보안적인 문제도 있고, 코드가 불필요한 파라미터를 받아서 동작을 멈출수도 있기 때문입니다. 그래서 permit 으로 원하는 파라미터만 가져오도록 합니다. 이를 Strong Parameter 이라고도 합니다. 이 코드를 좀 근사하게 쓰면 이렇게도 가능합니다.

def create
  @article = Article.new(article_params)
 
  @article.save
  redirect_to @article
end
 
private
  def article_params
    params.require(:article).permit(:title, :text)
  end

Article 클래스는 모델을 생성하면 자동으로 같이 생성됩니다. 모델을 만드는 코드는 다음과 같습니다. 주의해야 할게 있는데, 클래스 이름은 상수, 모델 이름은 단수, 해당 데이터베이스 테이블은 복수라는 것입니다. 생성된 모델은 app/models/article.rb 에 저장됩니다.

$ bin/rails generate model Article title:string text:text

그 다음 마이그레이션을 해주면 됩니다.

$ bin/rails db:migrate

(외부 서버에 마이그레이션할때는 아래 코드로)
$ bin/rails db:migrate RAILS_ENV=production

 

Article 보기 (read)

아직 article 을 볼 수는 없습니다. 왜냐하면 아직 구현하지 않았기 때문입니다. CRUD 에서 R(read) 에 해당하는 부분입니다. 이는 show 메서드로 구현할 수 있습니다. show 메서드는 다음과 같이 구현합니다.

# app/controllers/articles_controller.rb 에 메서드 추가

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

뷰도 생성해줍시다.

<!-- app/views/articles/show.html.erb -->

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>
 
<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

그러면 생성한 article 들이 이렇게 나타납니다. 주소는 생성한 article 의 순서에 따라 http://localhost:3000/articles/1 이나 http://localhost:3000/articles/2 와 같습니다.

 

 

전체 글 보기도 있어야겠죠? 이는 index 메서드로 만들 수 있습니다.

# app/controllers/articles_controller.rb
# index 메서드는 가급적 젤 위에 선언해주자.

def index
    @articles = Article.all
end

뷰도 만들어야 합니다. 뭐 당연하겠죠?

<!-- app/views/articles/index.html.erb -->

<h1>Listing articles</h1>
 
<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
    <th></th>
  </tr>
 
  <% @articles.each do |article| %>
    <tr>
      <td><%= article.title %></td>
      <td><%= article.text %></td>
      <td><%= link_to 'Show', article_path(article) %></td>
    </tr>
  <% end %>
</table>

다음과 같은 화면이 나타나면 성공입니다.

 

 

만들려고 했던 페이지는 모두 만들었습니다. 이제 페이지간 이동을 위해 링크를 만들어주겠습니다. 간단하니까 코드를 보시기 바래요.

 

<!-- app/views/welcome/index.html/erb 에 추가 -->

<!-- /articles 로 이동 -->
<%= link_to 'My Blog', controller: 'articles' %>

controller: 는 생략가능합니다. Ruby on Rails 는 똑똑하기 때문이죠.

<!-- app/views/articles/index.html.erb 에 추가 -->

<!-- 누르면 articles/new 로 이동 -->
<%= link_to 'New article', new_article_path %>

 

 

<!-- app/views/articles/show.html.erb 에 추가 -->

<!-- 이전 페이지로 갑니다 -->
<%= link_to 'Back', articles_path %>

 

 

<!-- app/views/articles/new.html.erb 에 추가 -->

<!-- 이전 페이지로 갑니다 -->
<%= link_to 'Back', articles_path %>

여기까지 Article 을 간단하게 만들어 보았습니다.

 

 

 

Article 수정하기 (update)

위에서 Article 을 만들고 읽는 것을 했었죠. CRUD 에서 C(create) 와 R(read) 에 해당하는 부분들이죠. 이제 나머지 U(update) 와 D(delete) 를 할 차례입니다.

 

먼저 만들어 볼 것은 article 을 수정하는 것입니다. article 을 수정할 때 입력하는 페이지를 만들어야 합니다. 지금까지 했던것과 크게 다르지 않습니다. 컨트롤러에 edit 메서드를 추가하면 됩니다. 해당 컨트롤러에 대한 뷰도 만들구요.

# app/controllers/articles_controller.rb 에 추가

def edit
    @article = Article.find(params[:id])
end
<!-- app/views/articles/edit.html.erb -->

<h1>Edit article</h1>
 
<%= form_with(model: @article, local: true) do |form| %>
 
  <% if @article.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@article.errors.count, "error") %> prohibited
        this article from being saved:
      </h2>
      <ul>
        <% @article.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
 
  <p>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </p>
 
  <p>
    <%= form.label :text %><br>
    <%= form.text_area :text %>
  </p>
 
  <p>
    <%= form.submit %>
  </p>
 
<% end %>
 
<%= link_to 'Back', articles_path %>

그럼 이제 update 메서드를 구현하면 됩니다. 여기서는 만약 업데이트가 되었다면 해당 글로 이동하고, 아니면 다시 edit 페이지로 이동하는 방법을 사용하겠습니다.

def update
  @article = Article.find(params[:id])
 
  if @article.update(article_params)
    redirect_to @article
  else
    render 'edit'
  end
end

 

거의 다 완성되었습니다. 이제 article 을 보여주는 index 뷰에 edit 을 위한 링크를 추가해주면 됩니다.

<!-- app/views/articles/index.html.erb -->

<% @articles.each do |article| %>
    <tr>
      <td><%= article.title %></td>
      <td><%= article.text %></td>
      <td><%= link_to 'Show', article_path(article) %></td>
      
      <!-- 추가한 코드 -->
      <td><%= link_to 'Edit', edit_article_path(article) %></td>
    </tr>
  <% end %>

 

show 뷰에도 링크를 추가해주겠습니다.

<!-- app/views/articles/show.html.erb -->

...

<%= link_to 'Edit', edit_article_path(@article) %>

 

여기까지 아무 문제없이 수행됩니다. 그런데 edit.html.erb 를 잘 보면 new.html.erb 파일과 되게 비슷합니다. 그도 그럴것이 new 나 edit 이나 어쨋든 article 에 대한 정보를 입력하는 부분이었으니까요. 루비의 중요한 철학중 하나는 같은 코드는 딱 한번만 사용하자 입니다. 그런 의미에서 edit 과 new 를 하나로 합쳐보겠습니다. 이를 위해서는 _form.html.erb 파일이 필요합니다.

<!-- app/views/articles/_form.html.erb -->

<%= form_with model: @article, local: true do |form| %>
 
  <% if @article.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@article.errors.count, "error") %> prohibited
        this article from being saved:
      </h2>
      <ul>
        <% @article.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
 
  <p>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </p>
 
  <p>
    <%= form.label :text %><br>
    <%= form.text_area :text %>
  </p>
 
  <p>
    <%= form.submit %>
  </p>
 
<% end %>

new 와 edit 의 중복된 코드가 _form.html.erb 에 들어갔습니다. 그러면 이제 new.html.erb 와 edit.html.erb 코드를 다음과 같이 바꾸어버리면 됩니다. 긴 코드는 다 지워버리자구요.

<!-- app/views/articles/new.html.erb -->

<h1>New article</h1>

<%= render 'form' %>

<%= link_to 'Back', articles_path %>
<!-- app/views/articles/edit.html.erb -->

<h1>Edit article</h1>
 
<%= render 'form' %>
 
<%= link_to 'Back', articles_path %>

어떄요, Ruby on Rails 재밌죠?

 

Article 삭제하기 (delete)

Article 을 삭제하려면 destroy 메서드를 선언하면 됩니다. 당연히 뷰도 만들어야겠죠? 간단하므로 코드로 남기겠습니다.

# app/controllers/articles_controller.rb

...

def destroy
    @article = Article.find(params[:id])
    @article.destroy
end
<!-- app/views/articles/index.html.erb -->

<% @articles.each do |article| %>
    <tr>
    
      ...
      
      <!-- 추가한 destroy 코드 -->
      <td><%= link_to 'Destroy', article_path(article),
              method: :delete,
              data: { confirm: 'Are you sure?' } %></td>
    </tr>
<% end %>

 

Article 검사하기

Article 에는 아직 구현해야 할 부분이 남아있습니다. 그 중에서는 값의 조건을 확인해보고 검증해야 할 필요가 있을 수도 있죠. 이에 대해 한번 알아보도록 하겠습니다.

 

articles/new 에서 Article 을 추가할 때 사용자가 Title 을 비워두는 경우가 있을 수 있습니다. 혹은 Title 의 길이제한을 두는 경우도 가능합니다. 컨트롤러에서 validates 를 사용해서 이를 제한할 수 있습니다.

# app/models/article.rb

class Article < ApplicationRecord
    validates :title, presence: true, length: { minimum: 5 }
end

이 코드는 title 이 반드시 존재해야 하며, 길이는 최소 5 가 되어야 한다는 것을 의미합니다. 이제 이 제한을 만족하지 않는 Article 은 저장되지 않습니다.

 

그럼 이제 Article 이 문제가 없다면 해당 글을 저장한 후 보여주고, 문제가 있다면 현재 화면을 다시 로드하는 코드를 구현하는 것도 가능합니다. 이를 위해 먼저 view 를 추가하겠습니다.

<!-- app/views/articles/new.html.erb 에 추가 -->

<!-- Error 처리 -->
  <% if @article.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@article.errors.count, "error") %> prohibited
        this article from being saved:
      </h2>
      <ul>
        <% @article.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

위에서 @article.save 가 article 이 저장되었는지에 대한 boolean 값을 저장한다고 했었죠. 이를 응용하면 근사한 컨트롤러를 만들 수 있습니다. redirect_to 가 아닌 render 를 사용하는 것에 반드시 주의하세요. redirect_to 를 사용하면 @articles 에 대한 정보가 남아있게 되어 페이지가 터집니다 문제가 발생할 수 있습니다.

# app/controllers/articles_controller.rb

# new 를 처음 눌렀을 때 Article 이 없는 경우 에러가 나는 것을 방지
def new
    @article = Article.new
end

def create
    @article = Article.new(params.require(:article).permit(:title, :text))
        
    if @article.save
        redirect_to @article
    else
        render 'new'
    end
end

그러면 이제 에러가 발생했을 때 근사한 메세지를 보여줄 수 있게 됩니다.

 

신기하죠? 저두요.

 

Comment 추가하기

위에서는 Article 모델을 통해 글을 생성하고 보는 등의 작업을 수행했습니다. 글만 있으면 재미없으니까 이제 새로운 모델인 댓글을 추가하도록 하겠습니다. 터미널에 다음 명령어를 입력해줍니다.

$ bin/rails generate model Comment commenter:string body:text article:references

그러면 Comment 모델을 위한 여러 파일들이 추가됩니다. 마이그레이션도 해줍시다.

$ bin/rails db:migrate

Comment 모델을 생성할 때 article: references 가 의미하는 것은 Comment 가 Article 에 속한다는 것입니다. 쉽게 말하면 댓글은 글에 속한다는 의미입니다. 이를 코드로도 확인할 수 있습니다. app/models/comments.rb 를 보면 다음과 같이 구현되어 있습니다.

# app/models/comment.rb

class Comment < ApplicationRecord
  belongs_to :article
end

단 우리는 하나의 글이 여러 댓글을 가질 수 있도록 만들 예정입니다. 그래서 Article 모델을 다음과 같이 조금 바꾸어주도록 하겠습니다.

# app/models/article.rb

class Article < ApplicationRecord
    has_many :comments
    
    ...
    
end

이정도면 모델 생성은 완료되었습니다. 이제 남은 것은 resources 와 컨트롤러를 만들어주는 것이죠. 코드는 다음과 같습니다.

# config/routes.rb

Rails.application.routes.draw do

  ...
  
  # article 과 comments 의 관계에 주의
  resources :articles do
    resources :comments
  end
    
  ...
  
end
# 컨트롤러 생성
$ bin/rails generate controller Comments

다음으로는 뷰를 생성해주어야 합니다. 방법은 Article 의 뷰를 생성하는 것과 똑같습니다. views 폴더에 .html.erb 파일로 html 템플릿을 만들고 controller 폴더에 .rb 파일로 메서드를 선언해 주는 것이죠. 코드는 아래와 같습니다.

<!-- app/views/articles/show.html.erb 에 추가 -->

...

<h2>Comments</h2>
<% @article.comments.each do |comment| %>
  <p>
    <strong>Commenter:</strong>
    <%= comment.commenter %>
  </p>
 
  <p>
    <strong>Comment:</strong>
    <%= comment.body %>
  </p>
<% end %>
 
<h2>Add a comment:</h2>
<%= form_with(model: [ @article, @article.comments.build ], local: true) do |form| %>
  <p>
    <%= form.label :commenter %><br>
    <%= form.text_field :commenter %>
  </p>
  <p>
    <%= form.label :body %><br>
    <%= form.text_area :body %>
  </p>
  <p>
    <%= form.submit %>
  </p>
<% end %>

...
# app/controllers/comments_controller.rb

class CommentsController < ApplicationController
    def create
        # 댓글이 어느 article 에 대한 것인지를 인스턴수 변수로 저장합니다.
        @article = Article.find(params[:article_id])
        @comment = @article.comments.create(comment_params)
        redirect_to article_path(@article)
    end
     
    private
    def comment_params
        params.require(:comment).permit(:commenter, :body)
    end
end

그러면 이제 글에 댓글도 볼 수 있습니다.

 

 

코드가 다소 지저분하다고 느꼈다면 칭찬을 드리겠습니다. 이 코드를 정리할 필요성이 좀 있는데 이를 근사한 말로 리팩토링한다고 말합니다. comment 에 대한 html 코드가 article 에 있는 것은 다소 이상하죠? 이를 먼저 고치는 걸로 걸로 합시다. 먼저 comment 를 생성하는 코드를 리팩토링합니다.

<!-- app/views/comments/_comment.html.erb -->

<p>
  <strong>Commenter:</strong>
  <%= comment.commenter %>
</p>
 
<p>
  <strong>Comment:</strong>
  <%= comment.body %>
</p>
<!-- app/views/articles/show.html.erb -->

...

<h2>Comments</h2>
<!-- 원래 여기에 있던 코드는 다 지우고 _comments.html.erb 를 render 해줍니다. -->
<%= render @article.comments %>

...

comment 를 보여주는 코드도 다음과 같이 리팩토링해주도록 하겠습니다.

<!-- app/views/comments/_form,html.erb -->

<%= form_with(model: [ @article, @article.comments.build ], local: true) do |form| %>
  <p>
    <%= form.label :commenter %><br>
    <%= form.text_field :commenter %>
  </p>
  <p>
    <%= form.label :body %><br>
    <%= form.text_area :body %>
  </p>
  <p>
    <%= form.submit %>
  </p>
<% end %>
<!-- app/views/articles/show.html.erb -->

...

<h2>Comments</h2>
<!-- 원래 코드는 다 지우고 새로 만든 _form.html.erb 를 render 해줍니다. -->
<%= render @article.comments %>

...

코드가 훨씬 깔끔해졌습니다.

 

Comment 삭제하기

이번에는 comment 를 삭제하는 것을 구현해보도록 하겠습니다. article 을 삭제하는 것과 큰 차이점이 없습니다. 설명 대신 코드로 보여드리도록 하겠습니다.

<!-- app/views/comments/_comment.html.erb 에 추가 -->

...

<p>
  <%= link_to 'Destroy Comment', [comment.article, comment],
               method: :delete,
               data: { confirm: 'Are you sure?' } %>
</p>

...
# app/controllers/comments_controller.rb 에 메서드 추가

...

def destroy
    # 댓글이 속한 글을 찾는다.
    @article = Article.find(params[:article_id])
    # 삭제하고자 하는 댓글을 찾는다.
    @comment = @article.comments.find(params[:id])
    # 삭제
    @comment.destroy
    redirect_to article_path(@article)
end

...

위에서 작성했던 것과 크게 다를 건 없어보입니다. 동작하는 것도 문제가 없어 보이지만 사실 보이지 않는 심각한 문제가 하나 존재합니다. 바로 글이 삭제되었을 때 그 글에 속한 댓글이 삭제되지 않고 데이터베이스에 불필요하게 남아있다는 것입니다. 그러면 언젠가는 저장소에 문제가 터지겠죠? 이를 위해서는 Article 클래스의 dependent 를 설정해주어야 합니다.

# app/models/article.rb 에 dependent 추가

class Article < ApplicationRecord
    has_many :comments, dependent: :destroy

    ...
end

그럼 이제 글을 삭제했을 때 댓글도 삭제됩니다. 정확하게 말하면, Article 의 destroy 메서드를 수행했을 때 belongs_to 관계에 있는 Comment 에서도 destroy 메서드도 함께 수행됩니다. 가이드에는 없는 내용이지만, destroy 대신 delete_all 를 사용하면 Article 이 삭제될 때 관련 Comment 들이 destroy 메서드 호출 없이 그냥 다 삭제됩니다. 참고하세요.

 

보안

마지막으로 보안 관련해서 몇가지 코드를 수정하고 글을 마무리하겠습니다. 지금까지 만든 blog 어플리케이션을 온라인으로 공개하면 아무나 글을 쓰거나 삭제할 수 있어서 문제가 발생할 수도 있겠죠. Ruby on Rails 에서는 이를 방지하기 위해 여러 훌륭한 옵션들을 제공합니다. 엄청 많지만 그 중에서 http_basic_authenticate_with 에 대해서 알아보겠습니다.

 

http_basic_authenticate_with 는 메서드를 수행할 때 이름과 비밀번호를 요구하는 간단한 보안 옵션입니다. Article 컨트롤러와 Comment 컨트롤러에 선언해주면 됩니다. Article 은 index 와 show 를 제외한 모든 것에 보안 증명이 필요하고, Comment 는 destroy 에만 설정하면 되겠죠? 코드는 다음과 같습니다.

# app/controllers/articles_controller.rb 에 한줄 추가

class ArticlesController < ApplicationController
    # index 와 show 를 제외한 모든 메서드를 수행했을 때 간단한 보안 증명을 요구합니다.
    http_basic_authenticate_with name: "name", password: "password", except: [:index, :show]
    
    ...
    
end
# app/controllers/comments_controller.rb 에 한 줄 추가

class CommentsController < ApplicationController
    # index 와 show 를 제외한 모든 메서드를 수행했을 때 간단한 보안 증명을 요구합니다.
    http_basic_authenticate_with name: "name", password: "password", only: :destroy
    
    ...
    
end

제대로 입력하면 기능이 수행됩니다.