Ruby on Railsでメッセンジャーライクな簡易2chビューアを作成してみる Part1

こんにちは。
最近Rails力が訛っているので、手慣らしにメッセンジャーライクな2chビューアを作成してみます。:D
gitのブランチは作業別に分けます。最初以外の作業中のコミットやプッシュなどの説明は省きます。
デプロイはherokuを使う予定です。
今回のパートでは、2chのスレッドをnokogiriとmechanizeというgemでスクレイピングしてとりあえず表示する所までやります。
ちなみに、2chからはスクレイピングやAPIによるデータ取得ができないので、2ch.scからスクレイピングします(:D)rz

## 環境
macOS Sierra 10.12.6
Visual Studio Code 1.16.0

Ruby on Rails 5.0.6
Ruby 2.3.1
rbenv 1.1.1-2-g615f844
MySQL 5.7.17

## GitHubリポジトリを作成
<img width="797" alt="スクリーンショット 2017-10-06 12.02.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/151736/7cc1dedb-0f5a-c467-0217-de9904e66b9b.png">


## GitHubリポジトリをクローン
各々のプロジェクトフォルダに移動し、
`$ git clone https://github.com/ユーザー名/リポジトリ名.git`

## Railsアプリ作成
プロジェクトフォルダに移動し、
`$ rails new アプリ名`

アプリ名とGitHubリポジトリ名が同じの場合は、上書きするかどうかのメッセージが出ると思うので、yと入力する。

## データベース作成
`$ rake db:create`

下記のように表示されたら作成成功
`Created database 'messenger-like-2ch-viewer_development'`
`Created database 'messenger-like-2ch-viewer_test'`

ターミナルでコマンドを入力してデータベースをマイグレートする
`$ rake db:migrate`

## サーバーを起動してブラウザでlocalhost:3000に接続してみる
`$ rails s`
サーバーが起動する

http://localhost:3000/
に接続すると、初期ページが表示される
<img width="864" alt="スクリーンショット 2017-10-06 12.04.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/151736/cc815368-dc3b-5bdd-4e9a-60fd7f133723.png">

## 必要なgemをインストール
Gemfileに各々の必要なGemを追加

```ruby:Gemfile
gem 'erb2haml'
gem 'haml-rails'
gem 'nokogiri'
gem 'mechanize'
gem 'font-awesome-rails'
```

追加したGemをインストールする
`$ bundle install`

## gemをインストールしたらサーバーを再起動する
サーバーを再起動しないと新たなgemが使えないので、ターミナルで`Ctrl+C`を押下して終了させる。
次に`$ rails s`で起動。

## GitHubリポジトリにinitial commitする
`$ git add .`
すべてのファイルを選択

`$ git commit -m 'initial commit'`
メッセージを入力し、コミット

`$ git push origin master`
masterブランチにプッシュ

## 作業用ブランチを作成し移動する
`$ git branch create-thread-viewer`
スレッド閲覧機能を作成するためのブランチを作成する

`$ git push origin create-thread-viewer`
作成したブランチをリモートリポジトリにプッシュする

`$ git checkout create-thread-viewer`
ブランチを移動する

## コントローラ・ビューの作成
`$ rails g controller Threads index`
※コントローラ名は複数形にすること
※コントローラ名の後にindexなどの文字を入れると、index.html.erbなどのビューも作成される(ここではindex.html.haml)

試しに
http://localhost:3000/threads/index
に接続してみると、ビューファイルが作成されていることが確認できる。

<img width="500" alt="スクリーンショット 2017-10-06 17.30.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/151736/9c4ef66e-ba79-5a46-fba0-bc4b794761e5.png">

## スレッド閲覧ページを作成する
イメージとしては、ChatPadのスマホ版のような感じです。
PC版はスマホ版の横幅を広くした感じにして行きます。
<img width="375" alt="IMG_1088.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/151736/f777980d-60e2-c604-50d0-c95b90b6cb8a.png">

Threadsコントローラ側にてスレッドをスクレイピングして、タイトルを@titleに、配列@repliesにレスを全部追加します。

```ruby:threads_controller.rb
class ThreadsController < ApplicationController
  def index
    agent = Mechanize.new
    agent.get('http://ikura.2ch.sc/test/read.cgi/anime2/1507217010/') do |page|
      html = Nokogiri::HTML(page.body)
      @title = html.css('h1').text;
      @replies = []
      html.css('dt').zip(html.css('dd')).each do |dt, dd|
        header = dt.text
        text = dd.to_html
        reply = {header: header, text: text}
        @replies << reply
      end
    end
  end
end
```

レスポンス部分をパーシャルで作ります。

```haml:_reply.html.haml
.reply
  .reply-header
    = simple_format(reply[:header])
  .reply-text
    = simple_format(reply[:text])
```

threads/indexでタイトルとレスポンスを表示します

```haml:index.html.haml
.container
  .site-header
    %span
      = @title
  .reply-box
    - @replies.each do |reply|
      = render 'reply', reply: reply
```

リセットcssにcontainerクラスのスタイルを追加します。

```scss:_reset.scss
.container {
  max-width: 50rem;
  margin: 0 auto;
  background-color: #333;
}
```

スレッド部分のcssを整えます。(メディアクエリでスマホ版のレス部分を微調整)

```scss:threads.scss
.thread-header {
  height: 2rem;
  background-color: #333;
  color: white;
  text-align: center;
  line-height: 35px;
  font-size: 17px;
  font-weight: bold;
}

.reply-header {
  font-weight: bold;
}

.reply-box {
  margin: 10px 10px 0 11px;
  padding-bottom: 20px;
  font-size: 12px;
}

.reply {
  margin: 10px 0;
  padding: 8px;
  display: table;
  background-color: #CCC;
  border-radius: 10px;
  position: relative;
}

.reply::before {
  content: '';
  position: absolute;
  left: -9px;
  top: 8px;
  display: block;
  width: 0;
  height: 0;
  border-top: 7px solid #CCC;
  border-left: 10px solid transparent;
}

@media screen and (max-width: 1024px){
  .thread-header {
    font-size: 15px;
  }
  .reply {
    word-break: break-word;
  }
  .reply-box {
    font-size: 10px;
  }
}
```

スレッドを1つスクレイピングして表示するところまではこれで完成です！(:D)rz
http://localhost:3000/threads/index にアクセスすると...

### PC版
<img width="838" alt="スクリーンショット 2017-10-10 15.02.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/151736/c78a3f5b-c6db-4e00-3d36-7ea502e6fdcd.png">

### スマホ版
<img width="320" alt="スクリーンショット 2017-10-10 15.03.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/151736/718aed61-c461-5452-55f1-4bd6d5d4e5f5.png">

次回は、スレッドリストを作るところまで進めます。(cssの微調整もあり)