あれやこれやしたRailsのモデル用Specファイル

subjectの挙動がよくわからないので要調査。

## Specファイル

```ruby

# -*- coding: utf-8 -*-
require 'spec_helper'

describe Member do

  let(:initialized_model) {Member.new}
  let(:valid_model) {FactoryGirl.build(:player)}
  let(:created) {FactoryGirl.create(:player)}

  shared_examples_for :can_find_by_id do |id|
    it {->{Member.find(id)}.should_not raise_error(ActiveRecord::RecordNotFound)}
  end

  shared_examples_for :can_not_find_by_id do |id|
    it {->{Member.find(id)}.should raise_error(ActiveRecord::RecordNotFound)}
  end

  describe 'valid_model' do
    subject {valid_model}
    its(:valid?) {should be_true}
  end

  context 'can save' do
    subject {valid_model}
    its(:valid?) {should be_true}
    its(:save) {should be_true}
  end

  context 'after save' do
    it_behaves_like :can_find_by_id, FactoryGirl.create(:player).id
  end

  context 'after delete' do
    m = FactoryGirl.create(:player)
    m.delete
    it_behaves_like :can_not_find_by_id, m.id
  end

  context 'can find by player number' do
    subject {FactoryGirl.create(:unique_member)}
    it {->{Member.find_by_player_number(subject.player_number)}.
        should_not raise_error(ActiveRecord::RecordNotFound)}
  end

  context 'when new' do
    subject { initialized_model }
    its(:valid?) {should_not be_true}
    its(:save) {should be_false}
  end

  context 'can join a team' do

    team = FactoryGirl.create(:team_base)
    subject {FactoryGirl.create(:player)}
    it do
      ->{
        team.add_member(subject)
        subject.reload
      }.should change(subject, :team).from(nil).to(team)
    end

  end

  context 'can leave from the team' do
    team = FactoryGirl.create(:team_base, member_count: 1)
    subject {team.members.find(:first)}
    it do
      ->{
        team.remove_member(subject)
        subject.reload
      }.should change(subject, :team).from(team).to(nil)
    end
  end

  describe 'name attrubute' do
    names = {empty: '', length_over: 'あいうえおかきくけこさしすせそ'}
    names.each do |k, v|
      context "set #{v}(#{k})" do
        subject { valid_model }
        it {->{subject.name = v}.should change(subject, :invalid?).from(false).to(true)}
      end
    end
  end

  describe 'player_number attribute' do
    context 'set nil' do
      subject {valid_model}
      it {->{subject.player_number = nil}.should_not change(subject, :valid?)}
    end

    numbers = {not_number: 'abcde', length_short: '1234',  length_over: '123456'}
    numbers.each do |k, v|
      context "set #{v}(#{k})" do
        subject { valid_model }
        it {->{subject.player_number = v}.should change(subject, :invalid?).from(false).to(true)}
      end
    end

    pn = FactoryGirl.create(:unique_member)
    subject do
      valid_model.player_number = pn.player_number
      valid_model
    end
    context 'set exist player number' do
      its(:save) {should be_false}
    end
  end
end
```

## FactoryGirl

```ruby
# -*- coding: utf-8 -*-

require 'faker/japanese'
FactoryGirl.define do

  # メンバテーブルの基本データ
  factory :member_base, class: Member do
    name { Faker::Japanese::Name.name }

    trait :type_player do
      member_type 1
    end

    trait :type_manager do
      member_type 2
    end

    trait :for_unique_check do
      player_number '99999'
    end

    # 選手
    factory :player, traits: [:type_player]
    # 指導者
    factory :manager, traits: [:type_manager]
    # 選手管理番号の一意チェック用
    factory :unique_member, traits: [:for_unique_check]
  end

  # チームとメンバーの中間テーブル
  factory :team_member do
    team_id 0
    member_id 0
  end

  # チームの基本データ
  factory :team_base, class: Team do
    ignore do
      member_count 0
    end
    name {"チーム:#{Faker::Japanese::Name.name}"}

    after_create do |team, evaluator|
      # 指導者を作成
      manager = FactoryGirl.create(:manager)
      FactoryGirl.create(:team_member, {team_id: team.id, member_id: manager.id})

      # 指定された人数分の選手を作成
      if evaluator.member_count > 0
        members = FactoryGirl.create_list(:player, evaluator.member_count)
        members.each do |player|
          FactoryGirl.create(:team_member, {team_id: team.id, member_id: player.id})
        end
      end
    end
  end
end
```