Rails Girlsを題材にRuby on Railsを勉強した際のメモ

# はじめに
[Rails Girls](http://railsgirls.jp/ "Rails Girls")を題材にRuby on Railsを勉強した際のメモ。

今回はRailsについての勉強が主目的であるため、「GitHubであなたのアプリを公開しよう」などは割愛した。

# 1. Railsインストールガイド
Ubuntu13.10を使用した。

 1. node.jsのインストール

 ```
 $ sudo apt-get install nodejs
 ```

 2. sqlite3のインストール

 ```
 $ sudo apt-get install libsqlite3-dev
 ```

 3. Ruby2.1.0のインストール

 必要なライブラリをインストールする。

 ```
 $ sudo apt-get -y install zlib1g-dev build-essential libssl-dev libreadline-dev git
 ```

 ruby-buildをインストールする。

 ```
 $ git clone git://github.com/sstephenson/ruby-build.git
 $ cd ruby-build/
 $ sudo ./install.sh
 ```

 バージョン管理ツールのrbenvをインストールする。

 ```
 $ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
 $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.profile
 $ echo 'eval "$(rbenv init -)"' >> ~/.profile
 $ exec $SHELL -l
 ```

 Ruby 2.1.0をインストールする。

 ```
 $ rbenv install 2.1.0
 ```

 どのディレクトリからもRuby 2.1.0を使える様にする。

 ```
 $ rbenv global 2.1.0
 ```

 4. Ruby on Rails4.0.3のインストール

 ```
 $ gem install rails
 ```

# 2. はじめてのRailsアプリ

## 1. アプリケーションを作る
* 新規アプリケーションの作成

 ```
 $ rails new railsgirls
 ```

 railsgirlsはアプリケーション名であり、任意の名前を付けることが可能。
 テストフレームワークにはTest::UnitフレームワークではなくRSpecを使うからtestディレクトリは不要という場合は下記コマンドを使用すると良い。

 ```
 $ rails new railsgirls --skip-test-unit
 ```

* サーバの起動

 ```
 $ rails s
 ```

 Railsに付随しているWEBRickをサーバとして起動する。

## 2. IdeaのScaffoldをする
* DBの作成

 ```
 $ rails g scaffold idea name:string description:text picture:string
 ```

 scaffoldとは、Railsに備えられている、コードを自動生成するジェネレータの一つ。scaffoldを実行することで、最低限のCRUDを行うWebアプリを作成することが可能。

 ideaはモデル名であり、任意の名前を単数形で指定する。ここで指定したモデル(idea)は、モデルのクラス名を複数形にしたテーブル(ideas)に自動的にマッピングされる(つまり、モデルideaとテーブルideasの関連付けが自動的に行われる)。

 ``` name:string... ``` の部分は[カラム名:型]の形式になっており、テーブルideasはnameとdescriptionとpictureの3つのカラムを持つことを指定している。指定できる型は[Railsドキュメント](http://railsdoc.com/rails "Railsドキュメント")を参考。

 scaffoldを実行すると **マイグレーションファイル** が生成される(db/migrate/prefix_create_ideas.rb)。prefixは20140308040813の様なUTCベースのタイムスタンプ。マイグレーションはDBに適用する変更を表すものであり、適用するとDBを更新することが、逆適用するとロールバックすることができる。

* マイグレーションの適用

 ```
 $ rake db:migrate
 ```

 未適用のマイグレーションを全て適用する。

 ちなみに、RakeとはRubyで記述されたビルドツールのこと。

### 補足
[Rails Girls](http://railsgirls.jp/ "Rails Girls")では触れられていないが、知っておくと便利と思われるコマンドを紹介する。

* マイグレーションの逆適用

 ```
 $ rake db:rollback
 ```

* テーブルへのデータの読み込み

 ```
 $ rake db:seed
 ```

 いちいちscaffoldで生成したインターフェースを使って、Webブラウザからデータを入力するのは面倒。で、要領良くテーブルへデータを読み込ませるための機能がこれ。

 db/seeds.rbを下記の様に編集した後、上記コマンドを実行するだけで良い。
 イメージファイル(下記例ではidea1.jpg)はapp/assets/images/に格納する。

 ```
 Idea.create(name: 'idea1', description: 'description of idea1.', picture: 'idea1.jpg')
 ```

## 3. デザインする
* HTMLとRailsの関係

 [Ruby on Railsチュートリアル](http://railstutorial.jp/chapters/a-demo-app?
version=4.0#top "Ruby on Railsチュートリアル")の2.2.2 MVCの挙動が分かり易くまとまっていると思う。

* Twitter Bootstrap

 Twitter Bootstrap(以下単にBootstrapと呼ぶ)とは、CSSフレームワークの一つであり、HTMLにCSSを読み込ませるだけでそれらしいデザインを簡単に適用できるもの。Bootstrapを使うメリットとしては

 * ブラウザの差異を修正してあるため、CSSに関する知識の無い人でも表示崩れの無いWebサイトを作ることが可能(対応ブラウザについては[Bootstrap](http://getbootstrap.com/ "Bootstrap")などで確認のこと)
 * レスポンシブWebデザインを簡単に作ることが可能

 などがある。
 Bootstrapについて勉強したい方は[【初心者向け】デザイナーのつまずかないBootstrap3](http://color-full-web.com/web/easy_bootstrap/ "【初心者向け】デザイナーのつまずかないBootstrap3")が参考になるかと思う。

## 4. 写真アップロード機能を追加する
* CarrierWave

 ファイルアップロード機能を提供するGem。
 GemとはRubyにおけるパッケージ管理システムのことで、RubyGemsとも呼ばれる。Gemを用いるとRubyで利用するライブラリのインストール/アップデート/アンインストール/パッケージ同士の依存関係の解決などを行うことができる。

* アップローダの作成

 ```
 $ rails g uploader Picture
 ```

 CarrierWaveで提供されているuploaderジェネレータを使って、Pictureという名前のUploaderクラスを作成する。
 ジェネレータにより、appディレクトリ内にuploadersディレクトリとapp/uplooadersディレクトリ内にpicture_uploader.rbが生成される。picture_uploader.rbを編集することで、アップロードできるファイルタイプの制限など、アップローダのカスタマイズを行うことができる。

* Ideaモデルにアップローダの追加

 ```
 $ mount_uploader :picture, PictureUploader
 ```

* image_tag()ヘルパーメソッド

 ```
 <%= image_tag(@idea.picture_url, width: 600) if @idea.picture.present? %>
 ```

 渡された引数を画像のソースとして扱い、HTMLのimgタグを生成する。
 第一引数(@idea.picture_url)は画像ファイルへのパス、第二引数(width: 600)はHTMLオプション(今回は画像の幅)である。他にどんなオプションがあるかは[image_tagリファレンス](http://railsdoc.com/references/image_tag "image_tagリファレンス")を参照のこと。

* 部分テンプレート
 部分テンプレートとは、ビューの一部を専用ファイルに収めたものであり、別のテンプレートやコントローラから呼び出すことが可能である。...と言われても良く分からないと思うので、今回のアプリでの使用例をもとに説明をする。

 localhost:3000/ideas/newページの表示を行っているファイル(app/views/ideas/new.html.erb)をみると、非常にスッキリしている(空行含めても5行)。

 ```app/views/ideas/new.html.erb
 <h1>New idea</h1>

 <%= render 'form' %>

 <%= link_to 'Back', ideas_path %>
 ```

 でも実際の表示をみると、上記ファイルには無いNameやらDescriptionやらを入力するコントロールなどがある。これらのコントロールは、そのコントロールを表示する専用ファイル(app/views/ideas/_form.html.erb)で指定されている。部分テンプレート(_form.html.erb)の内容をテンプレート(new.html.erb)に埋め込むには、テンプレート内の埋め込みたい場所で ``` <%= render ディレクトリ名/部分テンプレートファイル名 %> ``` 
と記述すれば良い(今回の例ではnew.html.erbの3行目に相当する)。

 テンプレートと部分テンプレートを区別するため、部分テンプレートファイル名はアンダースコア(_)始まりとなる。

## 5. routesを調整する
Railsではユーザのリクエストを表すURLからどのコントローラのアクションを実行するかを決定する。このURLとアクションを結びつけるルールをルーティングといい、その設定はconfig/routes.rbで行う。
現在(``` root to: redirect('/ideas') ```追加前)のルーティングは下記の通り。

| HTTPリクエスト | URL | アクション | 説明 |
|:-----------:|:------------:|:------------:|:------------:|
| GET | /ideas | index | 全てのideaを表示するページ |
| POST | /ideas | create | 新規ideaを作成するアクション |
| GET | /ideas/new | new | ideaを新規作成するページ |
| GET | /ideas/:id/edit | edit | 指定したidのideaを編集するページ |
| GET | /ideas/:id | show | 指定したidのideaを表示するページ |
| PATCH | /ideas/:id | update | 指定したidのideaを更新するアクション |
| PUT | /ideas/:id | update | 指定したidのideaを更新するアクション |
| DELETE | /ideas/:id | destroy | 指定したidのideaを削除するアクション |

下記一行をroutes.rbに追加すると、ルートパス http://localhost:3000/ にredirectというアクションが関連づけられ、ルートパスを開くとデフォルトページではなく、ideasページが開かれる様になる。

```
root to: redirect('/ideas') 
```

### 補足
* ルーティング内容の確認

 ```
 $ rake routes
 ```

# 5. あなたのアプリにコメント出来るようにしましょう

## 1. Commentのscaffoldをする
scaffoldの実施後は ``` rake db:migrate ``` を行うこと。

## 2. モデルに関係(relations)を追加する
リレーションシップを指定するメソッドには今回使用した ``` has_many ``` や ``` belongs_to ``` の他にも ``` has_one ``` や ``` dependent ``` などがある。
リレーションシップに関する説明は[RailsGuides](http://guides.rubyonrails.org/association_basics.html "RailsGuides")が参考になるかと思う。

## 3. コメントフォームの表示と編集
 * paramsオブジェクト

 ブラウザのリクエストで渡された全てのパラメータを格納するオブジェクト。

 * ideasとcommentsオブジェクトの関連付け

 ```
 $ @comment = @idea.comments.build
 ```

 buildについては[buildリファレンス](http://railsdoc.com/references/build "buildリファレンス")を参考のこと。

# 6. bootstrapを使ってモダンなデザインにしましょう
## 2. ナビゲーションを良くしよう
以下のコードだとアプリケーションをWebサーバ上の別の場所に移動した場合、URLは無効となる。また、RailsのURLに関するフォーマットが今後変更となった場合もURLは無効となる。

 ```
<li class="active"><a href="/ideas">Ideas</a></li>
 ```

上記問題を避けるために、アクションへのハイパーリンクを作成する ```link_to``` というヘルパーメソッドを使うと良い。

 ```
<li ><%= link_to 'New Idea', new_idea_path %></li>
 ```

## 3. アイデアリストをデザインしましょう

 * Bootstrapの12gridsレイアウト

 Bootstrapではグリッドレイアウト(画面を格子状に分割してレイアウトする手法)を採用しており、Bootstrap3ではグリッドの列数は12に固定されている。
 詳細は[Twitter Bootstrap 入門](http://www.wivern.com/twitterbootstrap3.html "Twitter Bootstrap 入門")を参考のこと。

 * ideasテーブルから3つのideaを一つのグループとして取り出す

 4カラムを3つ並べるレイアウト(一行に3つのideaを表示するレイアウト)にするため、3つのideaを一つのグループとして取り出している。

 ```
 <% @ideas.in_groups_of(3) do |group| %>
 ```

 例えば、6カラムを2つ並べるレイアウト(一行に2つのideaを表示するレイアウト)に変更したければ、 ``` in_groups_of(3) ``` を ``` in_groups_of(2) ``` に、 ``` class="span4" ``` を ``` class="span6" ``` にすれば良い。不足分は ``` nil ``` が入る。

 * ``` compact ``` メソッドを使い、配列 ``` group ``` から ``` nil ``` を取り除く

 ``` in_groups_of(3) ``` で不足分に ``` nil ``` が代入されているので、そいつを取り除く。

 ```
 <% group.compact.each do |idea| %>
 ```

## 4. ideaの詳細ページをデザインしてみましょう
 * Rails4で非推奨となったlink_toのconfirm

 Rails4ではlink_toのconfirmは非推奨となったので、(Rails4を使っている場合は)

 ```
 <%= link_to 'Destroy', @idea, confirm: 'Are you sure?', method: :delete %> |
 ```

 を

 ```
 <%= link_to 'Destroy', @idea, data: { confirm: 'Are you sure ?', method: :delete } %> |
 ```

 に変更する。

# 7. Carrierwaveを使って画像をリサイズしよう
``` bundle ``` 実行後はサーバの再起動を行う以外はチュートリアルに記載の手順通り。

 * ImageMagickとは何か

 様々なフォーマットの画像の作成/編集ができるフリーソフト。画像の一部切り出し/リサイズ/回転などが可能。

# 8. Deviceによる認証を追加してみよう
Step3でサーバの再起動を行うこと以外はチュートリアルに記載の手順通り。
新しく出てきたトピックを簡単にまとめる。

 * devise gemとは

 Railsアプリにログインの仕組みを組み込むためのgem。デファクトスタンダードになっている模 様。devise gemについてしっかりと学習したい方は[Ruby on Rails 3.0 日記](http://www.oiax.jp/rails/rails3.html "Ruby on Rails 3.0 日記")が参考になるかと思う。

 * エラー処理と通知

 Railsにはエラーの処理/通知に役立つ便利な機能として、 **フラッシュ** と呼ばれる構造が定義されている。フラッシュにはリクエストの処理過程でオブジェクトを格納することができ、そのセッションの次のリクエストの処理が完了するまで使用することができる。

 例えば、ログインしていない状態で登録内容を確認しようとした場合、エラーメッセージ(You need to sign in or sign up before continuing.)をフラッシュに格納し、sign_inページへのリダイレクトを行う。その際エラーメッセージがStep2で追記した下記部分に表示される。

 ```
 <% if alert %>
   <p class="alert alert-error"><%= alert %></p>
 <% end %>
 ```

# 参考書籍/URL
* [RailsによるアジャイルWebアプリ開発 第4版](http://www.amazon.co.jp/Rails%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%ABWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-%E7%AC%AC4%E7%89%88-Sam-Ruby/dp/4274068668/ref=sr_1_1?ie=UTF8&qid=1394253017&sr=8-1&keywords=rails+%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB "RailsによるアジャイルWebアプリ開発 第4版")
* [TECHSCORE](http://www.techscore.com/tech/Ruby/rails-4.0/ "TECHSCORE")