Rails4メモ　簡易なブログを作る その2

分からなかったら[RailsGuide](http://guides.rubyonrails.org/getting_started.html "RailsGuide")を見る。

コメント機能を追加する

```
> rails g controller Comments --skip-assets

create  app/controllers/comments_controller.rb
      invoke  erb
      create    app/views/comments
      invoke  test_unit
      create    test/controllers/comments_controller_test.rb
      invoke  helper
      create    app/helpers/comments_helper.rb
      invoke    test_unit
      create      test/helpers/comments_helper_test.rb
```

ArticleモデルにCommentモデルがたくさん紐づいているように設定する。

```
> rails g model Comment commenter:string body:text article:references
      invoke  active_record
      create    db/migrate/20130915051600_create_comments.rb
      create    app/models/comment.rb
      invoke    test_unit
      create      test/models/comment_test.rb
      create      test/fixtures/comments.yml
```

article: referencesを追記することによって他のテーブルへの外部キーを表すカラムを追加する。
モデルを追加したので下記のコマンドを打つ。

```
> rake db:migrate
```

models/comment.rbを開く。

```rb:comment.rb
class Comment < ActiveRecord::Base
  belongs_to :article
  validates :commenter, presence: true
  validates :body, presence: true
end
```

models/article.rbを開いて下記を追加。

```rb:article.rb
has_many :comments, dependent: :destroy
```

<strong>has_many</strong>はArticleモデル１つのレコードに多数のCommentモデルが紐づく。
1対多の関係。
<strong>has_many</strong>で指定する場合はcommentsと複数形で指定することに注意する。
dependent: :destroyはarticleのデータを削除したらそれに紐づくコメントのデータを削除するために必要。


```rb:routes.rb
Gorira::Application.routes.draw do
  root 'articles#index'
  resources :articles do
    resources :comments
  end
end
```

ルート設定する。articleのパスにcommentのパスが紐づいている設定にする。
下記のコマンド打ってルートを確認してみる。

```
> rake routes

 Prefix Verb   URI Pattern                                       Controller#Action
                root GET    /                                                 articles#index
    article_comments GET    /articles/:article_id/comments(.:format)          comments#index
                     POST   /articles/:article_id/comments(.:format)          comments#create
 new_article_comment GET    /articles/:article_id/comments/new(.:format)      comments#new
edit_article_comment GET    /articles/:article_id/comments/:id/edit(.:format) comments#edit
     article_comment GET    /articles/:article_id/comments/:id(.:format)      comments#show
                     PATCH  /articles/:article_id/comments/:id(.:format)      comments#update
                     PUT    /articles/:article_id/comments/:id(.:format)      comments#update
                     DELETE /articles/:article_id/comments/:id(.:format)      comments#destroy
            articles GET    /articles(.:format)                               articles#index
                     POST   /articles(.:format)                               articles#create
         new_article GET    /articles/new(.:format)                           articles#new
        edit_article GET    /articles/:id/edit(.:format)                      articles#edit
             article GET    /articles/:id(.:format)                           articles#show
                     PATCH  /articles/:id(.:format)                           articles#update
                     PUT    /articles/:id(.:format)                           articles#update
                     DELETE /articles/:id(.:format)                           articles#destroy
```

commentのshowメソッドの欄を確認してみると
/articles/:article_id/comments/:idとarticleの下にしっかりパスが紐づいてる。

controllers/comments_controller.rbを開く。

```rb:comments_controller.rb
class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.new(comment_params)
    if @comment.save
      flash[:notice] = "作成できました！"
      redirect_to article_path(@article)
    else
      render :template => "articles/show"
    end
  end

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

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

```

controllers/articles_controller.rbを開く。
showメソッドに以下を追加。

```rb:articles_controller.rb
def show
   @article = Article.find(params[:id])
   @comment = Article.find(params[:id]).comments.build
end
```

views/articles/index.html.erbを開く。
下記を追加。

```rb:index.html.erb
<%= link_to "新規作成", new_article_path %>
  <%= flash.notice %>
  <%= flash.alert %>
<hr>
<% @article.each do |f| %>
    <ul>
      タイトル：<%= link_to f.title, article_path(f)%>
    </ul>
    <ul>
      名前：<%= f.name %>
    </ul>
    <ul><br>本文：</br>
      <%= simple_format(truncate(f.content,:length => 1000)) %>
    </ul>
    <ul>
      作成日時：<%= f.created_at.strftime("%Y/%m月%d日(#{%w(日 月 火 水 木 金 土 日)[Time.now.wday]})") %>
    </ul>
    <ul>
      <%= link_to "編集", edit_article_path(f) %>&nbsp;：&nbsp;<%= link_to "削除", f,
    :confirm => "削除してよろしいですか？",
    :method => :delete %>
    </ul>
    <ol>
    <% f.comments.each do |comment| %>
      <li>名前：<%= comment.commenter %>
          <%= comment.created_at.present? ? comment.created_at.strftime("%Y/%m月/%d日(#{%w(日 月 火 水 木 金 土 日)[Time.now.wday]}) %T ") : comment.created_at %>
      </li>
      <%= simple_format(comment.body) %>
    <% end %>
    </ol>
    <hr>

<% end %>

```

views/commentsのフォルダに_form.html.erbファイルを作成する。
以下の追加。

```rb:_form.html.erb
<% if @comment.errors.any? %>
<h3>エラーが<%= (@comment.errors.count) %>件あります</h3>
  <% @comment.errors.full_messages.each do |msg| %>
  <ul>
    <li><%= msg %></li>
  </ul>
  <% end %>
<% end %>

<h2>コメント欄</h2>
<ol>

<% @article.comments.each do |comment| %>
  <li>名前：<%= comment.commenter %>
      <%= comment.created_at.present? ? comment.created_at.strftime("%Y/%m月/%d日(#{%w(日 月 火 水 木 金 土 日)[Time.now.wday]}) %T ") : comment.created_at %>
  <br><%= simple_format(comment.body) %>
  </li>

<% end %>
</ol>

<h2>コメント記入</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter, value: "名無し", size: 30 %>
  </p>
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body, :cols => 50, :rows => 10 %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

```

views/article/show.html.erbのファイルに下記を追加する。

```rb:show.html.erb
<%= flash.notice %>
<%= render "comments/form" %>
```

db/seed.rbにCommentモデルの初期データを追加する。

```rb:seed.rb
0.upto(300) do |abc|
  Comment.create(
  { article_id: [*1..50].choice,
    commenter: "鼻#{['子', '血', '糞', 'bon', nil].choice}",
    body: kuman(20)
    })
end

```

seedファイルを変更したので下記のコマンドを打つ。

```
> rake db:seed
```