YAMLのビックリマーク

rails-i18n/ja.yml at master · svenfuchs/rails-i18n · GitHub を見てなんだ?と思ったのでググったら、ずばりの質問があった。

Rails の config/locales/ja.yml での ! の機能とは? - QA@IT
%で始まってるけど、ただの文字列だよということを明示してるのか。

VPSで動かしてた小さいRailsアプリをHerokuに移行

DBも使ってないやつがなぜかVPS上で動いてたのでHerokuに移したメモ。

設定

$ git mv config/database.yml config/database.yml.example

# Gemfile
group :development, :test do
  gem 'sqlite3'
end
group :production do
  gem 'pg'
  gem 'rails_12factor'
end

$ brew install postgresql
$ bundle

$ git commit -am "Update settings for heroku"

公開

$ heroku login
$ heroku create <APP_NAME>
$ heroku addons:add heroku-postgresql
$ heroku push master

ドメイン

Herokuのアプリ設定画面でドメインを追加。

cname <SUB_DOMAIN> <APP_NAME>.herokuapp.com.

を設定。

`data: { confirm: 'Are you sure?' }`が2回表示される

なんだ?と思ったらpublic/assets/があった。
リモートサーバでassets:precompileがこけたから、ローカルでテストしたんだった。
その後消すのを忘れてたので2回呼ばれてしまっていた。
凡ミス。

bootstrap-sassをbundle updateしても反映されない

twbs/bootstrap-sass · GitHubapplication.scssで読み込んでいるdevelopment環境での話。

$ bundle update

しただけでは、application.cssが更新されないので、古いBootstrapを見てしまう。

$ touch app/assets/stylesheets/application.css.scss 

しても効果なし。
application.css.scssを適当に編集して画面を更新。その後戻したら行けた。

…本番でも起きた。

$ rake assets:clobber assets:precompile RAILS_ENV=production

した。

find_by(nil)を呼んだら警告を出すGem "where_is_nil"

名前はいいの思いつかなかったので仮。

find_by(nil) にハマるで書いたんだけど、またやっちゃう自信があったので、Railsの勉強がてら機械的に防止するGemを作った。

そもそもバグじゃないの?

find_by(nil) returns first record instead of nil · Issue #14867 · rails/rails · GitHub
ということなので、バグじゃない。仕様。

  • nil, 1, '1' => 最初のレコード
  • 'a' => エラー
  • 0 => nil

になる。

where_is_nil Gemは何をするか

find_by(nil)find_by(1)が呼ばれた時に、ログやエラーを出して、find_by(id: 1)の間違いじゃない?と警告します。

設定項目などはGitHubに。
tnantoka/where_is_nil · GitHub

find_byだけで、whereの時はnilでも何もしていない。
(GitHubで検索したらwhere(nil)はたくさん使われてたので。また、当初の目的はタイポ防止で、間違えてwhere(nil)することはあまりなさそうなため)

インストールと設定

# Gemfile
gem 'where_is_nil'

$ bundle

するだけです。

参考にしたGem

Gemは書き慣れてないので、いろいろ参考にさせていただいた。

alfa-jpn/kakurenbo · GitHub
yuki24/did_you_mean · GitHub
airblade/paper_trail · GitHub
plataformatec/devise · GitHub

The Basics of Creating Rails Plugins — Ruby on Rails Guides
公式のガイドもわりと充実してる。

一応動く状態になったので、個人プロジェクトで使っていこう。


以下メモ。

find_by(nil)した時に何が起きてるか

Railsのソースで関連しそうなところ(4.2.0)

find_by/where
arel

処理を追う

find_byはそのまま素通りして、whereになげる。

where内のcase文。
nilの場合はblank?がtrueになるので、selfがそのまま返される。
それがtakeされるので最初のレコードが取得される。

1やid: 1の場合は、where!が呼ばれる。

where_valuesが以下のように更新される。

  • { id: 1 } => [#<Arel::Nodes::Equality>]
  • 1 => [1]

あとはtakeの時にSQLに変換される。そこはarelの処理。

build_arelからcollapse_wheresが呼ばれ、以下のように変換される。

  • { id: 1 } => Equalityのまま変化なし
  • 1 => #<Arel::Nodes::Grouping>

それが、Arel::Nodes::And.newに渡される。

なんだかんだで最終的に、to_sqlされると、

irb> User.where(1).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE (1)"
irb> User.where(id: 1).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" = 1"
irb> User.where(nil).to_sql
=> "SELECT \"users\".* FROM \"users\""

となる。

後から気づいたけど、↑はrelationなので、whereとかを呼んだ後find_byした時の話。
User.find_byを直接呼んだ場合は、
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/core.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/querying.rb
が呼ばれてる。

最終的には同じ処理を通るのでよしとする。