Rails tutorial 学習メモ

# http://railstutorial.jp

web開発に関わる年数は長いですが、railsは初学者です。学習メモ。

## dir 構成

- |- rails-{ver}
    - |- prjA
    - |- prjB
    - |- Gemfile
    - |- vendor/bundle
    - |- .bundle/config 

とするのがよいように思う。
ここのGemfileは

```rb:Gemfile
source 'https://rubygems.org'
gem 'rails', '4.1.0'
```

のみ。

```
$ bundle install --path vendor/bundle
```

でinstall。で、各prjはprjの下のvendor/bundleにinstallする

## .bundle/config 

bundle install のオプションは

```
$ bundle install --path vendor/bundle --without production
```

これは remembered なオプションなので.bundle/configに記録される。
んでも、.bundle/configは .gitignoreするらしい。
これは悩ましい。
まあ、環境毎にモジュールのinstall場所も、対象モジュールを変えたりしたいのも分かるけど、オプションをみんなで(または自分の複数環境間で)共有したい時はどうするんだろう。

## モジュールのver

- Gemfile に最初に書く時は概ね、最新verでよいはず。
- でも、install後に、Gemfileにinstallされたverを書き足しておく一手間はかけておくべき。

- Gemfile.lock ってコミットする方がよいのかな。ちょっと仕組みが分かってない。
    - Gemfile.lockの一式は、verの整合性がとれた状態のはず。
    - Gemfileを更新した契機でGemfile.lockが更新される？


## .secretキー

- これあんま読んだことなかったけど重要。
- ちゃんと、.gitignoreする。
- config/initializers/secret_token.rb
- このコードが有用。なければ自動で作成。
    - session生成用だから環境によって違ってよいのか。 

## rails のお作法であり強力なところ

### session の使い方(8章)

- session 関数で利用する(ブラウザ内有効なsession)
- session[:remember_token] = user.id
    - このsessionオブジェクトは、ユーザーidをcookiesに保持することで、ページ移動後にもユーザーidを参照できるようにしています。cookiesはブラウザが閉じられると無効になります。アプリケーションは、ページごとに以下の呼び出しを行います。
    - User.find(session[:remember_token])
- *実際に動かしてみてない。

### Strong Parameters

- 以前は

```
@user = User.new(params[:user])
```

- と書けていた。が、これには、マスアサインメントの脆弱性を作ってしまうので、model でattr_accessible を作って制御してた。
- rails4 からは、

```
  @user = User.new(user_params)
    :
    :
  private

    def user_params
      params.require(:user).permit(:name, :email, 
                    :password, :password_confirmation)
    end
```

- として、使う(user_params とするのは慣習)

### 複数形にしてくれるhelper

```
pluralize(@user.errors.count, "error")
```
- 便利すぎるw

### flash メッセージ

- renderで表示したテンプレートを再描画してもリクエストと見なされません。このため、フラッシュメッセージはひとつのリクエストに対して期待よりも長い間消えずに表示され続けてしまいます。たとえば、無効な情報を送信するとサインインページにフラッシュメッセージが設定されて表示されます (図8.6)。ここでHomeページなどの別のページへのリンクをクリックすると、これはフォームが送信されてから最初のリクエストであるため、フラッシュメッセージが移動先のページでも表示されたままになってしまいます 
- flash.now は、他のリクエストが発生したらすぐにメッセージを消します。
    - んー。これって別のバグ起因にならんのかな。。
    - reload 時はもう一回セットされるから問題ないとして
    - でもそれって、flashのデフォでいいやんと思ってしまうのだけどそうじゃない理由はなんだろう。また考える。


## rails での自動テスト環境の構築

- Test::Unit は使わない

```
$ rails new sample_app --skip-test-unit
```
- gems

```
gem 'rspec-rails'
gem 'selenium-webdriver'
gem 'capybara'
```


- RSpecのinstall
    - これは、rspec --init と同等で .rspec とhelperを生成してくれるくらいのよう

```
$ rails generate rspec:install
```

- test が不要なCの作成

```
$ rails generate controller StaticPages home help --no-test-framework
```
- 結合テスト
    - Rspec ではrequest SPEC
    - spec/requests 以下。
``` 
$ be rails generate integration_test ***
```
    - で作成

### test環境では、secure password のコストを下げる(7章)

- config/environments/test.rb

``` test.rb
  ActiveModel::SecurePassword.min_cost = true
```

### どんなに小規模であってもよいのでビューで何らかのテストを行っておくことが重要(7章)

- view の生成レベルのエラーに気づけるので

## rails のmodel(というよりActiveRecord の特徴)

- user = User.new の時点では、オブジェクトをメモリ上に作成するだけ。
- user.save した時点で、insert 文が発行される
    - User.create では、即時insert (して、生成したオブジェクトが戻り値)
- user.destroy は、即時delete (create と対)
    - しかし、オブジェクトが戻る。

## rails(ruby)の命名の慣習

- Rubyがクラス名にキャメルケースを使う慣習があり (詳細は4.4で説明します)、また、キャメルケースの名前を使うことが好まれているためです。これらの慣習に必ず従わなければいけないということではありません。(同様にRubyでは、ファイル名をスネークケースで記述する慣習があります。このため Railsのgenerateスクリプトでは、 underscoreメソッドを使ってキャメルケースをスネークケースに変換しています。)

## generate のやり直し

- destroy を使う。でも、複数methodはあんまりうまくいかなそう。
    - 2つのmethod をgenerate し、1つをdestroy した時に、既に消されてしまうファイルもありそう。
    - んでも、2つ目のmethod もdestroy すれば元通りにはなる。
    - 消されすぎないように要注意か。

```
$ rails destroy controller StaticPages help
```

## 正規表現の作成のヘルパー(6章)

- http://www.rubular.com
    - 便利そう。

## ヘルパーの挙動(8章)

- viewからはすべてのヘルパーがデフォルトで利用できる。
- コントローラーでは明示的にincludeする必要がある。
    - session とかVからもCからも使いたい用途。

## postgres

- ほとんど使ったことないのだが。。

```
$ brew install postgres
$ sudo brew services start postgres
$ createuser -P -d sample_app
  # 普段使いのユーザーが管理権限を持っていて、postgresのinstallやservice起動をしているならユーザー指定は不要
  # ちなみに、brewだと、postgresユーザーは作成されないよう？
  # DB作成権限付きは、-d
```

- DB作成権限の付与を忘れたので

```
$ psql postgres
postgres=# alter role sample_app with createdb;
ALTER ROLE
postgres-# \q
```

- postgres6の時代以来、久々に使った。。
- これで、rake db:create できる

## Guard & Spork

```
$ be spork --bootstrap
```

その後、spec_helperで、guard とspork を連携

```
guard 'rspec', after_all_pass: false, cli: '--drb' do
  :
```

な感じ。ちなみに、doc ではcli: だが、deprecated って怒られるので、cmd: に。これで

```
$ be guard
```

でspork も起動できる。

- Sublime Text からtest を実行
    - Command-Shift-R: itブロック内のテストについては、テストを1回だけ実行します。describeブロック内のテストについては、一連のテストを実行します。
    - Command-Shift-E: 最後に実行したテストを再度実行します。
    - Command-Shift-T: 現在のファイルにあるテストをすべて実行します。

## bootstrap

### alert-error は、alert-danger になったようだよ(7章,8章)

- http://easyramble.com/instead-of-alert-error.html
- https://github.com/wmluke/angular-flash/pull/6