railsのparamsについて調べたのでメモ
今回はparamsのメソッドについてハマったので色々調べたメモです。
railsのバージョンは4.1.8でrubyのversionは2.1.5です(古いバージョンで辛い・・・
内容
作成した成果物を一覧で表示する処理を書いており、スクロールを行うと自動で次の成果物を表示するロジックを書いていた時に発生しました。
ロジックとしては、一定以上の座標に到達した時、非表示にしているlinkタグを動的に叩かせる処理で、linkタグはget形式です。
原因
getのパラメータの引数が膨大な長さになっており、それが原因でエラーになっていました。
処理の流れとしては
paramsを送信 (ブラウザ)→paramsを加工(サーバ)→linkタグを生成(ブラウザ)
みたいな流れです。
なぜ急に発生したのかと調べているとparamsを加工する処理が一番の原因でした。
サーバ側で〇〇_id_in[1,2,3.....]みたいな形のparamsを生成しており、
↑のparamsを元にgetのpathを生成すると
〇〇_id_in=1&〇〇_id_in=2&〇〇_id_in=3...
のような形式でpathが生成されました。
色々調べたところ、pathを作る時にparamsを元にしているっぽかったです。(配列で渡されたら↑のような形式になるのかな?未検証ですみません)
対応
- paramsを直接書き換えないようにする事(加工する時はdupなどで複製した物を使う)
- ransakを使うときは〇〇_id_inみたいなparamsをブラウザで生成しない事
まとめ
railsのparamsは直接触らずにdupなどで複製し、その複製したものに変更を加え流のが良いですね。あとransackの〇〇_in怖い・・・
参考リンク
destroy_allの挙動が思ったのと違ったのでメモ。
railsでまとめてデータを削除したいときにdestroy_allを使用していたのですが、実際に動いているsql文を見て想定と違ったので調べたのでメモ。
内容としては 数十万件のレコードを舐める時に1000件単位で削除を行おうと思ってコードを書いており、1000件のオブジェクトごとにdestroy_allをかけていました。
想定していた挙動は 1000件まとめてレコードを削除するdelete文が叩かれる事
でしたが、 実際は1レコードずつ削除するdelete文
が叩かれていました。
気になったのでrailsのapidockを見たところdestroy_allの実際の処理は配列のオブジェクトをeachで回して1つずつdestroyを叩いていました。
# File activerecord/lib/active_record/relation.rb, line 398 def destroy_all(conditions = nil) if conditions where(conditions).destroy_all else to_a.each {|object| object.destroy }.tap { reset } end end
勉強になりました。今回はこれで終わりです。
ssh先のサーバでrailsサーバを立ち上げるシェルを書いたのはいいけど、sshをkillするとrailsのプロセスが残ったままになったのでメモ
今回ハマった点ですが、タイトルの名の通りssh先のサーバでrailsサーバを立てるシェルを書いたのでが、ctrl + c で抜けるとsshはkillされてrailsのプロセスがssh先のサーバで残ったままだったので、解決方法を模索したメモになります。
ssh hostname 'rails s -b 0.0.0.0 -p 3005'
とコマンドを実行した時、ssh先のサーバでrailsサーバを立ち上げてテストを行おうと思っており、実際に問題なく立ち上げることには成功しました。しかし、ctrl + cで処理を終了させるとsshのプロセスだけ死んでrails sのプロセスだけずっと残ったままでした。
プロセスを確認すると↓のようになっており、
$ ps aux | grep ruby 508 17276 1.0 5.2 406732 155300 ? Sl 12:24 0:05 bin/rails s -b 0.0.0.0 -p 3105 508 17587 0.0 0.0 81796 836 pts/0 S+ 12:32 0:00 grep ruby
調べてみると、ttyとかptsの問題のようでした。 下記の記事でわかりやすく説明してくださってました。
簡潔に説明すると
ターミナルからアクセスしていると pts/
というものが表示され、?
と表示されている場合はdemonで立ち上がっているよという目印みたいでした。
上記を解決する方法ですが、
ssh -t hostname 'rails s -b 0.0.0.0 -p 3005'
-t
オプションを付ければ良いみたいでした。
LINE DEVELOPER DAY 2017に行って来ました
Line Developer Day に行って来ました 昨年も参加したのですが、ブログに書くのは今年が初めてになります。
受付
受付を完了するとお昼代としてヒカリエお食事券をいただきました。(2000円分) 写真を撮り忘れていたので、写真はありませんorz 受付を済ませオープニングセッションのホールへ向かう途中に ホームスピーカーが展示されていました。(めっちゃ欲しかったです
午前のセッション
午前のセッションは2つだけでLineのオープニングとLineが最近力を入れているAI、clovaの2本立てでした
Opening Session
openingはLINEがどのようにしていきたいという話と、もっとossに力を入れていくので、エンジニアのみなさんも力を貸してくださいという内容でした。私自身は勿論OKでした。エンジニアに優しいLINEのお願いとあっては断れるはずありません。
www.slideshare.net
The Technologies in Clova
clovaのセッションではlineがclovaをどのように定義し、これから展開していくかというお話でした。
一番びっくりしたのが、clovaを搭載したwavaは1年前にプロジェクトが始まったらしいです。地固めをしっかりしているLINEさんだからこその開発スピードなのかなと思いました。
(Line Developer Dayのアンケートに回答するとwaveが50名に当たるそうなので、めっちゃ欲しいです。ブログ書くので当たらないかなーって思ってました。)
www.slideshare.net
LUNCH TIME
ランチはお寿司を頂いて来ました。とっても美味しかったです。 ランチが終わると11階のカフェで休んでいました。 (これだけものが無料で提供されていたので、Lineの懐の深さに驚愕です。
午後のセッション
Gateboxのこれまでとこれから
Gateboxってなにかというとホームスピーカー1つですが、Amazon、Google、Lineと違うところは端末にキャラクターが存在しており、感情豊かなキャラクターがいるということでした。
いわゆる俺の嫁みたいな感じらしく、コンセプトムービーを見ましたが、これは是非欲しいなと思いました。
clovaとgateboxの提携が決定しているらしく、どちらかに吸収されるという事ではなく、互いに良いところを取り入れて来たいねという形での提携されるそうです。
www.slideshare.net
Paying back technical debt - LINE Androidクライアントの事
リファクタリングをしやすい文化と技術を取り入れましょうという内容でした。 ボーイスカウトルールはチームの文化に是非取り入れていきたいなと思いました。(めっちゃ耳が痛いですが
休憩
ここから1時間ほど元会社の上司の方とお話していました。
LINEにおけるBluetoothを活用した取り組みの紹介
主にline beaconの話でした。 本屋と連携しており、LINE漫画を読むことにより、限定特典などもらえるみたいでした。
Tappinessは自販機にline beaconを仕込んでおり、 lineを立ち上げて自販機に端末を近づけるとline payまたは現金で決済が出来、15ポイントでクーポンがもらえるみたいです。
なるほど、line beaconをlineの入った端末のネットを使ってサーバと連携するのか・・・(web buletoothを参考にしているらしいです。
line simple beaconはbuletoothの端末をline beaconに出来るソフトウェアらしく、ラズパイとか使って一回試して見たいなと思いました。
www.slideshare.net
Parallel Selenium Test With Docker
翻訳機を使っていたのですが、英語がかなり聞きやすかったので、英語聴きながら日本語を聞くと訳が分からなくなるので、途中から使うのをやめました。
内容はスライドを見ていただくと8割くらい理解できると思います。
docker+jenkins+seleniumでのテスト行う環境、良いなぁ。
www.slideshare.net
休憩
疲れたので次のセッションは参加せずに休憩してました。 フラフラしていると、上記セッションでお話をされていたTappinessの自販機を発見したので、利用させていただきました。
使い方はLineを起動すると自販機のline beaconが反応するので、Line Payまたは現金で決済を行うと買えました。
suicaと違ってドリンクポイントが貯まり、何回か利用するとお得になると思うと、あったら使うなと思いました。
BOT and the new Comfortableness
最後の技術セッションは message api とline loginの連携が出来るようになったみたいです。
グループを作成した時にユーザーのIDを取得できるようになったので、 個別のユーザーに対してのリアクションが可能に。
rich menuのレイアウトが自由に構築できるようになるみたいです。 自由なデザインが可能になるので、これは遊ぶ楽しさが増えますね。
ただし、rich menuのapiの更新はcommig soonらしいです。 line bot studioも近いうちにリリースされるみたいです。 ( 非エンジニアの人がカルーセルとかで出てくるものを選択してline botが作れるみたいです。コード書けなくてもできるというのが凄いなと思いました。
clovaのAPIも近い内に公開されるみたいです。
結論、rich menuのapiの更新・line bot studio ・clova apiはまだなので、とりあえずmessage apiとline loginで遊んでみてくださいとのことでした。
line api expertが公開されるみたいで、要は一緒にline api作ってくれる人募集との事でした。
www.slideshare.net
Closing Session
クロージングでは本日のセッションの振り返りとLineのこれからどのように展開していくのかというお話でした。京都にも開発拠点は学生との交流がメインであったりと、次を見据えているLineは改めてすごいなと感じさせられました。
www.slideshare.net
最後に
本日のアンケートに回答するとノベルティがもらえました。 その時にclova waveの抽選もあったのですが、筆者は見事当選しました!!
(左上 : ステッカー、右上 : マグカップ、下 : クローバー栽培キット (clova wave これで当分頑張れそうな気がします。
本当Line Developer Day最高でした。
開催して下さった関係者のみなさんありがとうございました!
来年も開催されたら是非参加させて頂きたいなと思っています。
linux(centos)の公開鍵を置いているサーバーにsshが出来なくて嵌まったのでメモ。
今回は公開鍵を置いているサーバーにsshが出来なくて嵌まって調べたメモになります。
状況
この状況でsshが出来ませんでした。
理由
view /var/log/secure
ここに
User your_username not allowed because account is locked
と書かれていました。
↑のログはssh_configの設定でパスワードの設定をしてないユーザーがsshしようとする時に出るみたいです(アクセスを弾いちゃいます)。
view /etc/shadow
↑を見るとUSERNAME:の次に「!!」と書いて有る場合は lockされているみたいです。(パスワードが設定されていると「!!」ではなくランダムの文字列になっているみたいです。
解決
passwd user_name
↑のようにloginユーザーのpasswordを設定してあげるとsshが出来るようになりました。
参考URL
Rspecでインスタンスメソッドのテストに苦労したのでメモ
今回はRspecでメソッドのテストをしたかったのですが、メソッド内で定義しているメソッド先の処理のテストは記述したくなかったので、それを解決したメモになります。
rubyのコード
# 今回テストしたかったのはTest1のexecuteメソッドになります Class Test1 def self.execute(test_params) Test2.execute(test_params) Test3.new(test_params).execute(test_params) # ←こいつが一番の曲者でした end end Class Test2 def self.execute(test_params) p test_params + 'test2' end end Class Test3 def initialize(test_params) @test = test_params + 'test3' end def execute(test_params) p @test + test_params + 'test3' end end
テストコード
require 'rails_helper' RSpec.describe Test1 do describe 'テスト1' it 'interfaceのテスト' test = double('Test3:00000000') allow(Test2).to receive(:execute).and_return(true) allow(Test3).to receive(:new).and_return(test) allow(Test3.new("")).to receive(:execute).and_return(true) Test1.execute(anything) end end end
Test3のテストコードですが、。最初は下記のように記述していました。
allow(Test3).to receive(:new) allow(Test3.new("")).to receive(:execute)
↑だとexecuteを呼ぶ時にno method errorがでます。
Test3で定義しているexecuteはクラスメソッドではなくインスタンスメソッドなので、インスタンスにメソッドを定義しないとエラーが出てしましました。
なので、
test = double('Test3:00000000')
↑でインスタンスを定義して
allow(Test3).to receive(:new).and_return(test)
↑でnewした時の戻り値にインスタンスを返えすようにします。
allow(Test3.new("")).to receive(:execute)
↑でインスタンスにexecuteメソッドを定義することによって
Class Test1 def self.execute(test_params) Test2.execute(test_params) Test3.new(test_params).execute(test_params) # ←こいつのテストが通るようになる end end
Test3のテストが通るようになります。(解決するまでにめっちゃ時間がかかりました。
参考URL
docker-composeでRAILS_ENVを切り替えて実行する方法を調べたのでメモ
今回はrspecを実行したいけど、わざわざdockerのコンテナの中に入って実行するのはイケてないと思い、調べたそのメモになります。
docker-compose exec test bash RAILS_ENV=test_docker rake db:migrate:reset RAILS_ENV=test_docker rspec
↑のコマンドを叩きたくないので
docker-compose exec test RAILS_ENV=test_docker rake db:migrate:reset docker-compose exec test RAILS_ENV=test_docker rspec ## rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:262: starting container process caused "exec: \"RAILS_ENV=test_docker\": executable file not found in $PATH"
と叩くと↑のようなエラーが出て上手く動きませんでした。
なので、
docker-compose run -e RAILS_ENV=test_docker test rake db:migrate:reset docker-compose run -e RAILS_ENV=test_docker test rspec
↑のようにrunする時に-eをつけると、envの指定が出来たので、上手く動きました。
ログインするというより、使い捨てのインスタンスを立てるって感じですね。