LoginSignup
9
12

More than 5 years have passed since last update.

vagrant環境+Ruby on Railsで簡易ブログソフトを作ってみる 後編

Posted at

前回に続いて、今回はブログの基本機能であるコメント機能を追加していく。

モデルをジェネレートするため、ターミナルに戻る。

rails generate model Comment commenter:string body:text article:references

するとdb/migrate/xxxxx_create_comments.rbができている。コマンドでマイグレートする。※xxxxxの部分は日付?的な感じの数字。

rake db:migrate

では、次にDBにコメントとアーティクルの関係を示す。(記事:コメント=1:多)
app/models/article.rbを編集する。

article.rb
class Article < ActiveRecord::Base
  has_many :comments
  validates :title, presence: true,
                    length: { minimum: 5 }
end

ルートの設定をする。
config/routes.rbを編集する。

routes.rb
Blog::Application.routes.draw do
  resources :articles do
    resources :comments
  end
  root 'welcome#index'
end

次はコメントのコントローラーを作る。

rails g controller Comment

showにコメントを作る欄を追加する。
app/views/articles/show.html.erb

show.html.erb
<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

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

<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br>
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

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

お次はコメントのコントローラーを編集する。
app/controllers/comments_controller.rb

comments_controller.rb
class CommentsController < ApplicationController
  def create
    @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

次はコメントの一覧を見られるようにする。
app/views/articles/show.html.erbに追加。

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 %>

続いて、リファクタリングをしていく。
app/views/comments/_comment.html.erbを作成。

_comment.html.erb
<p>
  <strong>Commenter:</strong>
  <%= comment.commenter %>
</p>
 
<p>
  <strong>Comment:</strong>
  <%= comment.body %>
</p>

そしてapp/views/articles/show.html.erbを編集する。

show.html.erb
<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

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

<h2>Comments</h2>
<%= render @article.comments %>

<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br>
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Edit Article', edit_article_path(@article) %> |
<%= link_to 'Back to Articles', articles_path %>

ちょっとすっきりした。レンダーが自動的にコメント数の分だけ繰り返してくれているらしい。
次はapp/views/comments/_form.html.erbを作成する。

_form.html.erb
<%= form_for([@article, @article.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br>
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

続いて、再度app/views/articles/show.html.erbを編集。

show.html.erb
<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

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

<h2>Comments</h2>
<%= render @article.comments %>

<h2>Add a comment:</h2>
<%= render "comments/form" %>

<%= link_to 'Edit Article', edit_article_path(@article) %> |
<%= link_to 'Back to Articles', articles_path %>

かなりすっきりした!!
じゃあ、次はコメントの削除機能を追加してく。
app/views/comments/_comment.html.erbを編集し削除リンクを付ける。

_comment.html.erb
<p>
  <strong>Commenter:</strong>
  <%= comment.commenter %>
</p>

<p>
  <strong>Comment:</strong>
  <%= comment.body %>
</p>

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

削除機能をコントローラーにも追加して機能を有効化する。
app/controllers/comments_controller.rbを編集。

comments_controller.rb
class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.create(comment_params)
    redirect_to article_path(@article)
  end

  def destroy
    @article = Article.find(params[:article_id])
    @comment = @article.comments.find(params[:id])
    @comment.destroy
    redirect_to article_path(@article)
  end

  private
    def comment_params
      params.require(:comment).permit(:commenter, :body)
    end
end

次は記事を消したときにコメントも削除されるようにする。
app/models/article.rbを編集。

article.rb
class Article < ActiveRecord::Base
  has_many :comments, dependent: :destroy
  validates :title, presence: true,
                    length: { minimum: 5 }
end

次はセキュリティ。誰もがブログやコメントを消したり書いたりできては困るので、、、。
app/controllers/articles_controller.rbを編集。

articles_controller.rb
class ArticlesController < ApplicationController

  http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show]

  def index
    @articles = Article.all
  end

  # snipped for brevity

コメントの方は削除のみ制限する。
app/controllers/comments_controller.rbを編集。

comments_controller.rb
class CommentsController < ApplicationController

  http_basic_authenticate_with name: "dhh", password: "secret", only: :destroy

  def create
    @article = Article.find(params[:article_id])
    ...
  end

  # snipped for brevity

これでできた!
超簡易的ブログの完成!!w
なるべく間違わないようにコピペしてますが、コードが間違ってたら教えてください。

9
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
12