Rails

ソースコードを読む

エンジニアとなり、RubyやRailsのプログラムを読み書きするようになって2年経った。 ソースコードを読む時のワークフローについて考えてみた時に、他人がどのようにソースを読んでいるのが気になった。 どのようにソースを読み、どのように理解するのか、一般解を知る前にまずは自分の方法を整理してみることにした。 ソースを読むメリット 間違いがない APIドキュメントから漏れていること、内部仕様もわかったり StackOverFllowに惑わされない 結果的に迷う時間の短縮 必要なモノ 気合 根性 pry bundle open IDE、Ctagsが使えるエディタ(Emacs, Vim, etc) 定義元ジャンプができればOK 言語、フレームワークの公式リファレンス(http://devdocs.io) 武器の使いドコロ 気合 Googleへ逃げず、ソースを読むという決断をするのために必要 根性 ソースコードを読み始めたが、よくわからんと途中で調べる事をやめてGoogleにすぐ逃げてしまうことを避けるために必要 pry 調べたいコードを実行させ、binding.pryでブレークポイントを作る edit METHOD_NAMEがどこから呼ばれているのかを見る。 Rubyのコードは実行時でないと、正しい呼び出し元がわからない。 また、pryはコード・リーディングやデバッグに便利様々な機能を持っている show-source METHOD_NAME でソースを読むこともできる ls OBJECT_NAMEでオブジェクトのクラスメソッド、インスタンスメソッドなどを確認できる IDEや、Ctagsが使えるエディタ(Emacs, Vim, etc) 定義元にエディタ上でジャンプする これだけのためにIDE使うという人は多い pryのeditで飛んでそこからはエディタでタグジャンプしたりする Ctags コマンドラインツール エディタがメソッドの定義元を調べるための索引tagsを提供 tagsがある場合、vimはデフォルトでc-]押せば定義元にジャンプできる(タグジャンプ) 万能ではなく、ジャンプ先がたまに間違っていることも Gtags(GNU GLOBAL)をいじるともっと賢い索引が手に入るらしい vim使ってる場合は、rails-vimプラグインがRails用にタグ生成コマンドを提供している ファイルサイズが大きく、利用するか否かは個人の環境に依存するため、.gitignoreへtagsを追加しておくべき。 bundle open bundle open LIBRARRY_NAME ライブラリ内のソースの在処(ディレクトリ)を開く README.mdを読んだり、lib/から関係していそうなところをおもむろに開いてみたりしている。 特に自分が使っているバージョンのREADME.mdを読むということに関しては最速。 言語、フレームワークのリファレンス (好きなツールで) リファレンスをいつでも読めるようにしておくことは重要 自分はDevDocsをよく使う DevDocsの特徴 リファレンスなんでも横断検索ツール Rails, Lodash, jQuery, Angular, Reactなど大抵ある オフライン機能があり、ブラウザにキャッシュさせることで、インターネット接続環境がなくても閲覧できる

mysqlで特定のテーブルのDumpをのみ取得する

必要となった背景 1つのコンテンツに対してそのコンテンツに含まれる複数のカテゴリの組み合わせを元におすすめのコンテンツを表示する。 動的に表示させようとしたが、現行のままでは動的に出すのは厳しく、バッチ処理でおすすめコンテンツの情報をキャッシュすることにした。 本番環境の裏側で実行させようと考えたが、非常に遅く、1ヶ月ほど時間がかかってしまうため、 一度本番のDumpを取得した上で別の環境でバッチを回し、その結果を本番環境へロードさせたほうが良いということになった。 テーブル別のDump いつもDB一括でMySQL workbenchでDumpを取得しているなど、mysqlコマンドに疎い。 今回は他のテーブルは必要なかったので、必要なテーブルのDumpのみを取得する方法を調べた。 下記コマンドでDumpを取得する。複数テーブルの場合は続けてテーブル名を入力すればよい。 また、今回の本番環境、隔離環境はRailsを利用しており、migrationにて既にテーブルが作成されている。 そのため-tオプションにてCREATE TABLE文をスキップさせる mysqldump -u <USERNAME> -p -t <DBNAME> <TABLENAME1> [ <TABLENAME2> ... ] > <DUMPFILENAME>.sql Dumpのインポート 下記コマンドでインポート mysqll -u <USERNAME> -p <DBNAME> < <DUMPFILENAME>.sql seed_fuで入れる場合 mbleigh/seed-fu という主に環境整備時に利用するものGemがある。 テストデータやシードデータの導入の利用される。 自分は実データをmysqlからdumpしてseed_fu用のfixtureを生成するrakeタスクを作成しており、ユースケースによってはこちらを利用する。 db:dump_seed_fu[model]で実行。 db:seed_fuで使えるseedデータがdb/fixtures内に生成される。 Special Thanks MySQL で特定のテーブルのみをバックアップ - Easy Ramble mbleigh/seed-fu

Rspecでインスタンス変数が参照できない

Rspecの世界からController内メソッドでインスタンス変数@hogeを利用した場合は、 直接Rspecからインスタンス化された@hogeは別物である。 まず、この事実を理解すべきだった。 Controllerの中の値をテストする Rspec側からRailsのController側でインスタンス化された値を評価する場合はassigns(:hoge)で参照するとよい。 また、RspecからDBアクセスして取り出す方法もあるのでこちらも忘れずに。 expect(Model.last.name).to eq 'modelname'で評価する。 どちらもどのような値がアサインされていればよいのかを意識してテストを書く。 その他 itブロック・contextブロック・describeブロックの中で定義した変数のスコープはその中に限る。 そのため、スコープを飛び越えて同じ値を扱うためにはインスタンス変数を利用する必要がある。 はじめてのテストということでハマってしまった。 テストではRailsの世界の変数か、Rspecの世界の変数なのかを明確に意識する必要があった。 実行中のプログラム内なのか、その外なのかを常に意識する。 RequestヘッダをRspecで作ってそれをRailsに投げる。 Railsの中のController内で、どのような値がアサインされるかテストする。 どの世界の値を取得して何と比べるのか。 何をテストすべきかを意識していれば回避できる問題。