Rails で`find_by_id`に渡す引数はString でもいけるんだって
# 普通のやつ User.find_by_id 1 => #<User id: 1, name: "yachibit", ...> # Stringを引数に渡すと... User.find_by_id '1' => #<User id: 1, name: "yachibit", ...> # このへんも同じく User.find '1' => #<User id: 1, name: "yachibit", ...>
SUGEEE!! つい最近知りました。
よくよく考えたらいつも使わせて頂いてたわけなんですが...
パラメーターで渡ってくる値はString なのでController でレコードを引くときに、いつもお世話になっています。
# params[:id] # => '1' User.find params[:id]
Rails さんは本当によく出来ているなあと、ただただ感嘆させられるばかりです。 パラメーターを渡すだけで、いい感じによろしくやってくれるあたりの仕事ぶりは、自分も見習わなければならないなと襟を正されます。
余談はさておき、
User.find "" User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 0 LIMIT 1
WHERE 'users'.'id' = 0
と言ってやがるということは、やはりRails は何処かでto_i
してるはずだ。ぜひとも、お目にかかりたと思い、Rails のコードを読み始めたのですがアレ?? 実際to_i
している箇所は見当たりませんでした(たぶん)。
どうやらActiveRecord::FinderMethods
のこの辺りが怪しそうですが。
うーん、ちょっとよくわからないです。
def find_with_ids(*ids) raise UnknownPrimaryKey.new(@klass) if primary_key.nil? expects_array = ids.first.kind_of?(Array) return ids.first if expects_array && ids.first.empty? ids = ids.flatten.compact.uniq case ids.size when 0 raise RecordNotFound, "Couldn't find #{@klass.name} without an ID" when 1 result = find_one(ids.first) expects_array ? [ result ] : result else find_some(ids) end end def find_one(id) if ActiveRecord::Base === id id = id.id ActiveSupport::Deprecation.warn "You are passing an instance of ActiveRecord::Base to `find`." \ "Please pass the id of the object by calling `.id`" end column = columns_hash[primary_key] substitute = connection.substitute_at(column, bind_values.length) relation = where(table[primary_key].eq(substitute)) relation.bind_values += [[column, id]] record = relation.take raise_record_not_found_exception!(id, 0, 1) unless record record end
落穂拾い
上に載せたfind_one
メソッドの冒頭。
if ActiveRecord::Base === id id = id.id ActiveSupport::Deprecation.warn "You are passing an instance of ActiveRecord::Base to `find`." \ "Please pass the id of the object by calling `.id`" end
はじめて読んだ時この部分がwhut? でした。id = id.id
とかちょっと何言ってるのかw
ですが、なるほどRails はどうも、こういう書き方もできるということなのです。
me = User.find_by_user_name! 'yachibit' User.find me
ただし、この書き方はdeprecated なので、
"Please pass the id of the object by calling .id"
という具合に怒られます。
Crafting Rails 4 Applications: Expert Practices for Everyday Rails Development (The Facets of Ruby)
- 作者: José Valim
- 出版社/メーカー: Pragmatic Bookshelf
- 発売日: 2014/02/04
- メディア: Kindle版
- この商品を含むブログを見る