blueberrycakeのブログ

railsとwebサービスについて書いています

RSpecでmodelのattr_accessibleをテストする

RSpecでmodelのattr_accessibleをテストできないかと、調べていたところ

stackoverflowで良さげなマッチャがありました。

RSpec::Matchers.define :be_accessible do |attribute|
  match do |response|
    response.class.accessible_attributes.include?(attribute)
  end
  description { "be accessible :#{attribute}" }
  failure_message_for_should { ":#{attribute} should be accessible" }
  failure_message_for_should_not { ":#{attribute} should not be accessible" }
end

このコードをspec/support/be_accessible_matcher.rbで保存します。

以下がmodelの全てのカラムのaccessbileをテストするコードになります。

beforeでaccessibleなカラムのシンボルの配列を定義して下さい。

context 'attr_accessbie' do
  before do
    @obj = obj.new
    @accessible = [:aaa, :bbb, :ccc]
  end
  it 'check all columns accessible' do
    @obj.class.column_names.each do |name|
      if @accessible.include?(name.to_sym)
        @obj.should be_accessible name.to_sym
      else
        @obj.should_not be_accessible name.to_sym
      end
    end
  end
end

rake db:rollbackでadd_indexするときは注意

migrationでunique制約の付いたindexを削除するために以下のmigrationファイルを作成します。

def up

  remove_index :tables, :column

end

 

def down

  add_index :tables, :column, :unique => true

end

これをmigrateしてもこの時点では問題ありません。

但し、columnの内容が重複するレコードが存在した状態で、元に戻すと以下のエラーになります。

rake db:rollback

Mysql2::Error:   Duplicate entry   ''   for   key   'index_tables_on_column': CREATE   UNIQUE   INDEX   `index_tables_on_column`   ON   `tables` &nbsp (`column`)

unique制約のindexが作成されると、既存のレコードに制約チェックが掛かるのでエラーとなりますね。

これを回避するには、以下の方法が考えられます。

  • テーブルを空にしておく
  • 制約チェックに引っかからないように、データの内容をセットしておく

modelを使わずに、optgroupタグを含んだセレクトボックスを作る方法

grouped_options_for_selectを使用します。

コントローラー上であらかじめ出力したい内容を配列で作成します。

各配列の最初の要素が<optgroup>として使用され、2番目の要素は<option>とvalue属性になります。

  @grouped_selectdata = [
    ['表題1', [['内容1-A', 0], ['内容1-B', 1], ['内容1-C', 2]]],
    ['表題2', [['内容2-A', 3], ['内容2-B', 4], ['内容2-C', 5]]],
    ['表題3', [['内容3-A', 6], ['内容3-B', 7], ['内容3-C', 8]]],
  ]

この配列をselect_tagとgrouped_options_for_selectで組み合わせます。

 <%= select_tag "sample", grouped_options_for_select(@grouped_selectdata) %>

このような表示になります。

f:id:blueberrycake:20120326100915p:plain

rails3.2.1でproduction.logが出力されない

railsのバージョンを3.2.1にアップグレードして以降、production.logが出力されていないことに気付く。

ネットで調べてみると、同じ事例を発見。

https://github.com/rails/rails/issues/4277

3.2.2にアップグレードすると解消するようなので、アップグレードしたらきちんと出力されました。