既存のアプリがRail 4.2.5, Ruby2.3.3で書かれています.
Rubyはそのままで,Railsを4.2.10へアップデートしたらRSpecテストもうまくいきました.
しかしRailsを4.2.10から5.0.6へアップデートしたところRSpecテストで失敗するようになりました.
調べた結果,RSpecのテーブル更新のある項目で失敗します.ActiveRecordの挙動が変わっているのと思ってます.
RSpecのログを見ると,ActiveRecordの吐き出すSQL UPDATE文にて,カラムが更新値にセット去れる文がなくなってます.具体的には.
Rails4.2.10(成功する)
抜粋
log
1Processing by TestAttribController#update as HTML 2 Parameters: {"test_attrib"=>{"id"=>"24", "test_id"=>"25", "attrib_type"=>"aaa", "attrib_key"=>"change_key", ・・・ 3UPDATE `test_attrib` SET `attrib_type` = 0, `attrib_key` = 'change_key' WHERE `test_attrib`.`id` = 24
Rails5.0.5(失敗する)
log
1Processing by TestAttribController#update as HTML 2 Parameters: {"test_attrib"=>{"id"=>"24", "test_id"=>"25", "attrib_type"=>"aaa", "attrib_key"=>"change_key", ・・・ 3UPDATE `test_attrib` SET `attrib_key` = 'change_key' WHERE `test_attrib`.`id` = 24
パラメータの受け渡しは出来ているようですが,UPDATE文のカラム(attrib_type)が抜け落ちてます.
抜け落ちているカラムの型が,Rail側ではenumなのが影響していると思います.
Rails4.2.10では成功するので,Rails5.0.6でのActiveRecordの挙動が変わっているのだと思います.
Rails5.0.6でのコードとしては,どのように実装するのでしょうか?
また,設定等でRails4.2.10と同じような挙動になるのでしょうか?
お手数ですが,お分かりの方,どんな情報でも良いのでヒントを教えていただけないでしょうか?
以下はモデル,コントローラ,RSpecコードです.
ruby
1# モデルのコード 2class TestAttrib < ActiveRecord::Base 3 belongs_to :test 4 5 enum attrib_type: [:aaa, :bbb, :ccc] 6 7 validates :attrib_type, presence: true 8 validates :attrib_key, presence: true 9end 10 11# コントローラのコード 12class TestAttribController < ApplicationController 13 14 # PATCH /test_attrib/:id 15 def update 16 @test_attrib= TestAttrib.find(params[:id]) 17 valid_success = lambda do 18 @test_attrib.save! 19 redirect_to action: :show, id: @test_attrib.id 20 end 21 @test_attrib.attributes = test_attrib_params 22 if @test_attrib.valid? 23 valid_success.call 24 end 25 end 26 27 private 28 29 def test_attrib_params 30 params.require(:test_attrib).permit(:attrib_type, :attrib_key) 31 end 32end 33 34# RSpecのコード 35RSpec.describe TestAttribController, type: :controller do 36 describe 'PATCH #update' do 37 let!(:test) { create(:test) } 38 let!(:test_attrib) { create(:test_attrib, test: test) } 39 before do 40 @edit_attr = test_attrib.attributes 41 @edit_attr[:attrib_type] = 'aaa' 42 @edit_attr[:attrib_key] = 'change_key' 43 end 44 subject { patch :update, id: test_attrib.id, test_attrib: @edit_attr } 45 it '変更が反映されること' do 46 subject 47 change_test_attrib= TestAttrib.find(test_attrib.id) 48 # ここで:attrib_typeが更新されてないので失敗する 49 expect(change_test_attrib).to have_attributes(attrib_type: @edit_attr[:attrib_type], attrib_key: @edit_attr[:attrib_key]) 50 end 51 end 52end 53
あなたの回答
tips
プレビュー