怖話はminitestに書き換えつつあるんですが、Bizerでは他の開発者に気を使ってrspecを使っています。

Bizerをrails4.1に上げたので、「ヒャッハー、デフォルトでtravel_toが使えるからtimecop削除できるぜー!」と思ったのですがrspecじゃそのままじゃ使えない。(クソがぁ

Before:

it 'coupon is expired.' do
  # FIXME: travel_to in rails 4.1
  Timecop.travel(2014, 5, 10, 0, 0, 0) do
    expect(expired_coupon_user.free_by_coupon?).to be_false
  end
end

After:

# spec/spec_helper.rb:
RSpec.configure do |config|
  config.include ActiveSupport::Testing::TimeHelpers
end
it 'coupon is expired.' do
  travel_to Time.new(2014, 5, 10, 0, 0, 0) do
    expect(expired_coupon_user.free_by_coupon?).to be_false
  end
end

今までTime.nowDate.todayを内部で使うメソッドはテストしやすいように

def metrix(now = Time.now); ... end

みたいに書いてたんですが、デフォルトで気軽にtravel_toが使えるならやらなくていいかな!

C-t: カーソル部分のタグにジャンプ

C-o: 前いた場所に戻る(tagに限らずいつも使いまくるヤツ)

g C-t: タグ候補が複数ある場合に候補一覧を表示

この3つだけでクッソはかどる

Xcodeとかの機能がうらやましい

IDEでは当然の機能ですが、クラスやメソッドの定義に飛べるのって便利ですよね。vimやemacsでは設定すればできるんだろうけどやってる人あんまり見ない。

開いてるbuffer内のものしか飛べないとか、明示的にtag生成コマンド実行とか論外。

そんな折、Gemfileのgemを含めて保存時自動tag生成してくれるvim-tagsというpluginがとても良かったのでご紹介。

szw/vim-tags

vim-tagsの設定

$ brew install ctags
# ~/.vimrc:
Bundle 'szw/vim-tags'
let g:vim_tags_project_tags_command = "/usr/local/Cellar/ctags/5.8/bin/ctags -f tags -R . 2>/dev/null"
let g:vim_tags_gems_tags_command = "/usr/local/Cellar/ctags/5.8/bin/ctags -R -f Gemfile.lock.tags `bundle show --paths` 2>/dev/null"
set tags+=tags,Gemfile.lock.tags

macデフォのctagsはbsdで色々違うのでbrewで入れてfullpath指定。

ファイル保存時にtagsファイルを生成。ちょっと遅くなるので非同期実行するvim-dispatch pluginとの連携も試してみたいと思います。

tpope/vim-dispatch

とにかく機能が細かくgemに分割される昨今。これははかどる!

2.5 Cookies serializer

Applications created before Rails 4.1 uses Marshal to serialize cookie values into the signed and encrypted cookie jars. If you want to use the new JSON-based format in your application, you can add an initializer file with the following content:

Rails.application.config.action_dispatch.cookies_serializer = :hybrid

cookieのserializerがrubyのMarshalからJSONに変わったって部分。

これcookieがバージョンまたいでないと発生しないからテスト面倒だねえ・・・。

ほぼ全部インターンの@hir_aikさんのお陰で怖話をrails3.2から4.0.5にアップデートできました。

やったー!勢いにのって4.1行くぞー!

2011年5月22日のrails3.0.7が最初のコミットでちょっと古くなってきましたが、railsアップデートを諦めた時がサイトが死ぬときと心得て頑張ります。

ActiveRecordのデフォルトではORDER BY区は省略されてるので、「ポスグレでデフォルトの並びってどうなってるんだろう?」と思って調べました。

SELECT - PostgreSQL 9.3.2文書

ORDER BYが指定されない場合は、システムが計算過程で見つけた順番で行が返されます

(略)

ORDER BY句を使うと、結果行を指定した式(複数可)に従ってソートすることができます。 最も左側の式を使って比較した結果、2つの行が等しいと判断された場合は、1つ右側の式を使って比較します。その結果も等しければ、さらに次の式に進みます。 指定した全ての式で等しいと判断された場合は、実装に依存した順番で返されます。

なんとなくINSERT順で出るのでは?と思ってましたが、実装依存なようなので、並びに意味がある箇所では必ず明示的に指定したほうが良さそうです。

SQL92や99、MySQLやSQLiteではどうなってるんだろう?

default_scopeでid ascとかにしとくべきか?でもARのdefault_scopeってバグを踏みやすい勝手な印象が付いてしまっていて過信するのもためらわれる…。

ActionMailerでマルチバイトのメールを送る時下記のように三行書く。

mail = NoticeMailer.charging(user, charge)
mail.transport_encoding = '8bit'
mail.deliver

プロジェクトの中にはNoticeMailer.posted_questionとかいくつかあるし、他のmethodでも他のMailerクラスでも一行で書きたいんだけどどのファイルにどう書くのがキレイかなあ?

追記:

tkawaさんのコメントを受けて実装された。

NoticeMailer.charging(user, charge).deliver

以前はコレだったけど、

puts "-----------------------------------"
puts @posts.inspect
puts "-----------------------------------"

railsのdebugの疑問 - komagata

今はputsしてPowのログを見る方式にした。(ログを見るのはtailかConsole.app)

# app/controller/home_controller.rb:
class HomeController < ApplicationController
  def index
    puts 'foo'
  end
end

Powの標準出力と標準エラー出力はlogに向いてるのでただputsするだかけなのは楽だ。

アプリの一部では使うからjbuildrのgem入れてるけど基本的にscaffoldでjson使いたくない場合。

# config/application.rb:
module Rails
  class Application < Rails::Application
    config.generators do |g|
      g.jbuilder false
    end
  end
end

昨日EdTech Hackathonに行って久しぶりに色々なWeb関係の方の空気に触れて思った事。

俺はrails好きで強力だし楽しいなーと思うんだけど、

「GoogleからJSのシングルページでもSEO的にペナルティが全く無くなったらサーバーサイド要らねんじゃね?mBaaSで良くね?」

とか

「ちょっとしたサーバーサイドの処理はPHPで良くね?エンジニア多いし、安いし、技術的負債とかセキュリティ・ホールとか経営者からしたらたいして気にならないし、実際の所よくわからないし、来年どうなってるかわからんし。」

とか

「railsエンジニアとか単価高い割に何やってるのかわからないし。テストを書いてます?もっとこうガーッと派手に動く機能追加してくれねえかなあ?」

とか

「長期的なプラットフォームとかはガッツリ作ってくれて構わないけど、もっと雑でいいから短命のモバイル・アプリ量産してくれねえかな?」

とか、そういう雰囲気がWeb業界にあって(俺の被害妄想)、railsが死ぬとしたらもっと強力なフレームワークが出てくるってのじゃなくて、

「railsスゴイのはわかったけど、そういう方向性のスゴさとか我々要らないし、 あと何か上から目線でrubyエンジニアも扱い辛いです。老害乙。」

みたいな感じで、死んでいくのかな、そうだったら嫌だな、と思いました。

皆どうやってるんだろう。

僕の場合、debuggerはstep実行が必要で無い限り使わない。(step実行が必要な程難しい問題が滅多に無いので殆ど使ってない)

 railsのdebug系の記事は定期的に上がるけど、実際にdebuggerを使ってるところを見たこと無い。

結局、

puts "@posts: #{@posts.inspect}"
とか、他の出力と混ざって見つけづらいので、
puts "-----------------------------------"
puts @posts.inspect
puts "-----------------------------------"

などと書いてrails sしたconsoleで確認している。loggerを使っても他の出力に埋もれるので結局putsする。もう何年も使ってるのにこれはショボイ気がする。

Ruby on Rails Guidesを見るとTagged Loggingというのがのっている。logにtagを付けてtail -fgrepすれば埋もれないのかも。
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
logger.tagged("BCX") { logger.info "Stuff" }
しかし、いちいちブロックで囲む必要があると面倒でputsしてしまう気がする。

railsのloggerとは別のloggerをAppName.loggerとかに設定してlog/app_name.logに出したりするのがいいのだろうか?