Rails5機能簡易まとめ


![](http://findicons.com/files/icons/1607/ruby_on_rails/128/ror_logo.png)

# [Model]()
## Active Model
### AttributeMethodsモジュール
### Callbacksモジュール
登録
実行
スキップ
停止
リレーションシップのCallBack
条件付きCallBack
CallBackClass
トランザクションCallBack

before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save

before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save

before_destroy
around_destroy
after_destroy

after_initialize
after_find

after_touch

### Conversionモジュール
### Dirtyモジュール
### Validationsモジュール




Ruby on Rails-View
[View]()

Ruby on Rails-Controller
[Controller]()

Ruby on Rails-Debugging
[Debugging](https://railsguides.jp/debugging_rails_applications.html)

Ruby on Rails-API
[Rails API Server](https://railsguides.jp/api_app.html)





# [Testing](https://railsguides.jp/testing.html)

## 基本
全てのRailsアプリケーションには3つの環境がある
それぞれの環境におけるデータベース設定は`config/database.yml`で行う

* development
* test
* production

## [Fixture](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html)

* YAMLで記述
* 特定のDBに依存しない
* 1つのモデルにつき1つのFixture
* ERBが使用できる
* 全てのFixtureを自動的に読み込み、テストで使用

```yml:users.yml
# Sample Fixture
david:
  name: David Heinemeier Hansson
  birthday: 1979-10-15
  profession: Systems development
 
steve:
  name: Steve Ross Kellock
  birthday: 1974-09-27
  profession: guy with keyboard
```

```yml
# belongs_to/has_many関連付けの場合
# fixtures/categories.ymlの内容:
about:
  name: About
 
# fixtures/articles.ymlの内容
one:
  title: Welcome to Rails!
  body: Hello world!
  category: about
```

```yml
# ERBを使用した場合
<% 1000.times do |n| %>
user_<%= n %>:
  username: <%= "user#{n}" %>
  email: <%= "user#{n}@example.com" %>
<% end %>
```
## Modelのユニットテスト

* ある値が別の値と等しいかどうか
* このオブジェクトはnilかどうか
* コードのこの行で例外が発生するかどうか
* ユーザーのパスワードが5文字より多いかどうか
* `test_helper.rb`に追加したメソッドはすべてのテストで利用できる
* テストを実行するには、テストDBが最新の状態で構成されている必要がある
* 全てのmigrationが完了している場合、`db/schema.rb`や`db/structure.sql`をテストDBに読み込む
* テストにパス: . (ドット)
* テストに失敗: F
* エラー発生: E
* [TDD](http://andrzejonsoftware.blogspot.jp/2007/05/15-tdd-steps-to-create-rails.html)
* [assertion](http://docs.seattlerb.org/minitest/Minitest/Assertions.html)
* Rails固有のassertionもある

```rb:article_test.rb
# ActiveSupport::TestCaseのすべてのメソッドを利用できる
# ActiveSupport::TestCaseのスーパークラスはMinitest::Test
class ArticleTest < ActiveSupport::TestCase
end
```

## Controllerの機能テスト

* Webリクエストが成功したか
* 正しいページにリダイレクトされたか
* ユーザー認証が成功したか
* レスポンスのテンプレートに正しいオブジェクトが保存されたか
* ビューに表示されたメッセージは適切か

### getメソッドに渡せるもの

* コントローラ内のアクション(アクション名は文字列またはシンボル)
* アクションに渡すリクエストパラメータに含まれるオプションハッシュ1つ(クエリ文字列パラメータや記事の変数など)
* リクエストで渡されるセッション変数のオプションハッシュ1つ
* flashメッセージの値のオプションハッシュ1つ

### getやpostを使用すると、利用できるハッシュ

* assigns - ビューで使用するためにアクションのインスタンス変数として保存されるすべてのオブジェクト。
* cookies - 設定されているすべてのcookies。
* flash - flash内のすべてのオブジェクト。
* session - セッション変数に含まれるすべてのオブジェクト。

### 利用可能なインスタンス変数

* @controller - リクエストを処理するコントローラ
* @request - リクエスト
* @response - レスポンス

### HTTPとヘッダーとCGI変数を設定する 

```rb
# HTTPヘッダーを設定する
@request.headers["Accept"] = "text/plain, text/html"
get :index
 
# CGI変数を設定する
@request.headers["HTTP_REFERER"] = "http://example.com/home"
post :create
```

### テンプレートとレイアウトが正しいかどうか

* `assert_template`一回の呼び出しで同時にテンプレートとレイアウトをテストできない
* パーシャル (部分レイアウト) が使用されている場合は、パーシャルにもアサーションを行なう必要がある

```rb
test "index should render correct template and layout" do
  get :index
  assert_template :index
  assert_template layout: "layouts/application"
  assert_template layout: "layouts/application", partial: "_form"
end
```

## Viewのテスト

* assert_select(セレクタ, [条件], [メッセージ])
* assert_select(要素, セレクタ, [条件], [メッセージ])
* ブロックを使用可能
* [assert_select](https://github.com/rails/rails-dom-testing/blob/master/lib/rails/dom/testing/assertions/selector_assertions.rb)

```rb
assert_select "ol" do |elements|
  elements.each do |element|
    assert_select element, "li", 4
  end
end
 
assert_select "ol" do
  assert_select "li", 8
end
```

## Integration test

* 複数のコントローラ同士のやりとりをテスト
* ActionDispatch::IntegrationTestから継承

## SetupとTeardown
ActiveSupport::Callbacksに実装されている

```rb
  # 各テストが実行される直前に呼び出される
  def setup
    @article = articles(:one)
  end
 
  # 各テストの実行直後に呼び出される
  def teardown
    # @article変数は実際にはテストの実行のたびに直前で初期化されるので
    # ここで値をnilにする意味は実際にはないのですが、
    # teardownメソッドの動作を理解いただくためにこのようにしています
    @article = nil
  end
```

## Routing 

```rb
test "should route to article" do
  assert_routing '/articles/1', {controller: "articles", action: "show", id: "1"}
end
```

## Mailer

* メールが処理 (作成および送信) されていること
* メールの内容 (subject、sender、bodyなど) が正しいこと
* 適切なメールが適切なタイミングで送信されていること
* 結果の出力と、Fixtureを比較

### Unit test

```rb
# inviteというアクションで知人に招待状を送信するUserMailerという名前のメイラー
require 'test_helper'
 
class UserMailerTest < ActionMailer::TestCase
  test "invite" do
    # メールを送信後キューに追加されるかどうかをテスト
    email = UserMailer.create_invite('me@example.com',
                                     'friend@example.com', Time.now).deliver_now
    assert_not ActionMailer::Base.deliveries.empty?
 
    # 送信されたメールの本文が期待どおりの内容であるかどうかをテスト
    assert_equal ['me@example.com'], email.from
    assert_equal ['friend@example.com'], email.to
    assert_equal 'You have been invited by me@example.com', email.subject
    assert_equal read_fixture('invite').join, email.body.to_s
  end
end
```

### Functional test
メール配信メソッドを呼び出し、その結果適切なメールが配信リストに追加されるかどうかをチェック
期待されたタイミングでメールが送信されるかどうか

```rb
require 'test_helper'
 
class UserControllerTest < ActionController::TestCase
  test "invite friend" do
    assert_difference 'ActionMailer::Base.deliveries.size', +1 do
      post :invite_friend, email: 'friend@example.com'
    end
    invite_email = ActionMailer::Base.deliveries.last
 
    assert_equal "You have been invited by me@example.com", invite_email.subject
    assert_equal 'friend@example.com', invite_email.to[0]
    assert_match(/Hi friend@example.com/, invite_email.body.to_s)
  end
end
```

## Helper
ヘルパーメソッドの出力が期待どおりであるかどうかをチェック

```rb
class UserHelperTest < ActionView::TestCase
  include UserHelper
 
  test "should return the user name" do
    # ...
  end
end
```



Ruby on Rails-Deploy
[Capistrano](http://labs.gree.jp/blog/2013/12/10084/)