rspecでハマったので備忘録

rspecでテストを書こうとしたのですが、理解が浅いこともあり手間取ったのでメモを。

 

ブラウザ上のでは問題なく動いていた機能について、requestspecを以下のように書いたけれど http500のエラーが。。。なぜ?

describe 'GET#show' do
let(:user) {create(:user)}
let(:log) {create(:log, user_id: user.id)}
before do
user = create(:user)
end

it 'リクエスト' do
get log_path log.id
expect(response.status).to eq 200
end
end

 

エラーが起こっている状態を確認するために、一度処理を止めて確認

it 'リクエスト' do
get log_path log.id
binding.pry
expect(response.status).to eq 200
end

 

ターミナルから以下コマンドでhtmlファイルとして吐き出して確認すると

undefined method `strftime' for nil:NilClass のエラーが!

File.write("tmp/debug.html", response.body)

 

 

strftime・・・はて、なんだっけ?

 

確認すると、日付のカラムが空白になっていたことがエラーの原因でした。

ブラウザ上では登録時にselectタグを使っていて、強制的に何かしらの日付が選択される仕様でした。そのためvalidationをかけておらず、modelテストではエラーが出ずの状態。

 

開発環境とテスト環境が別物ということを改めて実感。開発環境であれやこれやいじって、だいぶ時間をとられました。

予想外の事態が起きたときは、やはりその環境下での状態を見なくちゃダメですね。。。。

参考サイト:https://qiita.com/SoarTec-lab/items/9214150bae70f4b590b2

 

railsとjsでお絵かき

railsで簡単なお絵かき機能を実装したのでメモ

html5canvasを使うだけ。特にgemなどは必要なしです。

 

間違い、ご指摘等ありましたらお願いします!

 

 

1.  絵を描くためのキャンバスを作成

#html.haml
%canvas#test{height: "500", width: "900"}
#btn_clear 消去

 

canvasタグが絵を描くためのキャンバスになります。

キャンバスのサイズはcssで指定すると、

ペン入れした時にペンの位置がなぜかズレます。。。

htmlの中で規定すると正しく認識されました。

2行目は書いたものが消せるようにボタンを設置。

 

 

2.  jsでお絵かき機能を実装

キャンバス内でマウスをクリックしたまま動かすと、動きに合わせて線が描かれます。

クリックから手を離すと線を描くのを停止。

消去ボタンを押すと、書いたものがすべて消去されます

js
 
$(document).on('turbolinks:load', function(){
var canvas = document.getElementById('test');
var cnv = $('#test')
if (canvas.getContext) {
 
var ctx = canvas.getContext('2d');
 
flag = false;

cnv.on('mousedown', function(e){
flag = true
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
});

cnv.on('mouseup mouseout', function(){
flag = false
})

cnv.on('mousemove', function(e){
if(flag){
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
}
})

$("#btn_clear").on('click', function(){
ctx.clearRect(0, 0, canvas.width, canvas.height)
})
}
})

 

$(document).on('turbolinks:load', function(){
var canvas = document.getElementById('test');
var cnv = $('#test')
if (canvas.getContext) {
var ctx = canvas.getContext('2d');

ctx.lineWidth = 5
ctx.strokeStyle = "#ff0000"

 
flag = false;

cnv.on('mousedown', function(e){
flag = true
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
});

cnv.on('mouseup mouseout', function(){
flag = false
})

cnv.on('mousemove', function(e){
if(flag){
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
}
})

$("#btn_clear").on('click', function(){
ctx.clearRect(0, 0, canvas.width, canvas.height)
})
}
})

線を描く時は、大きく3つのイベントのもとで処理を進めています。

 ①マウスのクリック(mousedown)

  フラグを立て、パスをリセット(beginPath)、線の開始点を定義する(moveTo)

 ②指が上がる、もしくはキャンバスからフレームアウト(mouseup mouseout)

  フラグを折る

 ③マウスを動かす(mousemove)

  フラグが立っている時に限り、マウスの位置を認識し、線を引く

 

書いたものを消すときは、範囲を明確に指定しないとダメみたいです。

今回はキャンバス全体を指定して消してしまっています。

 

 

本当に簡単ですが、一応これで物を書くことはできます。

線の太さや色も変えられますが、今回はとりあえず割愛。

jsの変数の取り方でハマったのでメモ

jsを使って動的に変数を定義し、それを出力するアプリを作ろうとした時の話。

DOMを変数として定義して、そこからパラメータを引っ張り出そうとしたのですが、2回以上変数を変えようとした時、パラーメータを上書きできずにハマったのでメモ。

間違い、足りない部分等ありましたらご指摘ください。

 

 

結論、値渡しか参照渡しかということでした。

jsにおいてオブジェクト型は参照渡しだそうで・・・

DOMとしてではなく、直接パラメータの値を引っ張り出さなくちゃならないようです。

 

値渡し: 値そのものの情報が渡される(値そのものが変数に入る)

参照渡し:参照するためのメモリの場所が渡される(メモリに記録された値が変数に入る)

 

 

 

以下、奮闘記

JS
$(document).on('turbolinks:load', function(){
$('.colorPreview').on('change', '#opacity_switch', function(){
var opa_switch = document.getElementById('opacity_switch').value;
var targetColor = $(this).data('color')
if(opa_switch == 2){
$('.box').css('background-color', `#${targetColor}`)
}
  })
})

①あるエレメントにdata属性を持たせ、欲しいパラメータを入れておく

②スイッチを入れた時にその値を読み込み、出力する

という機能を実装しようとした際、繰り返しdata属性の値を変化させて読み込ませるとうまくいかない。初めの値のまま上書きがされない。。。

 

var targetColor = $(this).data('color')のすぐ下にconsole.log(this)を入れて確認すると、エレメントのdata属性の値は更新されている。。。なぜ?

 

ではconsole.log($(this).data('color'))では・・・やっぱり2回以上やると、こっちは値が更新されない。

 

 

調べてみると、jsでは変数の値の取ってき方が2種類あるらしく、冒頭にあった値渡しと参照渡し。

 

ならばDOMとしてではなく、エレメントのプロパティから直接引っ張ってきた値を代入すればいいのかな???

JS(改)
$(document).on('turbolinks:load', function(){
$('.colorPreview').on('change', '#opacity_switch', function(){
var opa_switch = document.getElementById('opacity_switch').value;
var targetColor = document.getElementById('preview').style.getPropertyValue('background-color')
if(opa_switch == 2){
$('.box').css('background-color', `#${targetColor}`)
 
 
}
})
})

 

いけました!

 

 

参考サイト:

https://mnivore.com/blogs/archives/32

https://qiita.com/migi/items/3417c2de685c368faab1