Help us understand the problem. What is going on with this article?

Ruby on Rails のquery attributeを使ってみる

結論: blank?とpresent?の代わりにattribute名?が使える(一部気をつける必要あり)

背景: integerのarrayを足しあげたかった(nilの可能性があり)

元々の私のコード...

[ここはhogekeyにもつObjectの配列].reject(|obj| !obj.hoge.nil?).sum(:hoge)

reject(|obj| !obj.hoge.nil?) でhogeがnilのものを取り除き、 sum(:hoge) でnilを取り除いたhogeを足しあげるつもりでした。

修正版

[ここはhogekeyにもつObjectの配列].select(&:hoge?).sum(:hoge)

reject(|obj| !obj.hoge.nil?)select(&:hoge?) になりました。
hoge?がtrueに評価されるものをselectするようにしました、ここが今回学んだことです。
attribute名?という表現ができることです。

解説

類似記事が既にあります
私の元々のコードはBad smellのするよくないコードだったようです。(参考ページ)

Rails本体のコードも見てみました。
このcase文が該当の箇所のようです。
case文もまとめると、、、

まずtrue なら true、false, nil なら falseですね

when true        then true
when false, nil  then false

次にレシーバに指定のattributeがある場合とない場合で大きく切り分けられるようです。

if !type_for_attribute(attr_name) { false }
  if Numeric === value || !value.match?(/[^0-9]/)
    !value.to_i.zero?
  else
    return false if ActiveModel::Type::Boolean::FALSE_VALUES.include?(value)
    !value.blank?
  end
elsif value.respond_to?(:zero?)
  !value.zero?
else
  !value.blank?
end

!type_for_attribute(attr_name) { false } にてレシーバに該当のattribute名がなければtrueとなります。
その上で、Numeric === value || !value.match?(/[^0-9]/)の場合(数字)、0の時false、それ以外はtrueとなります。
数字以外の場合は、falseの時はfalse、それ以外の時はblank?の結果が帰るようです。

次はレシーバに該当のattribute名がある場合です。
value.respond_to?(:zero?) で zero?を持つ場合は !value.zero? が評価され0の時false、それ以外はtrueとなります。
zero?を持たない時は、!value.blank?の結果が帰るようです。

まとめ

多くの場合でattribute名.blank?attribute名.present?の代わりに使えるなと思いました。
気をつけたいのは、0の時にfalseになるということですね。
参考記事でも言及されていました。
私がしたかったことは単純に足し上げだったので0が弾かれても困りませんが、場合によっては困ることもあるかなと思いました。

ここまで読んでいただきありがとうございました。
間違い等あればご指摘くださいまし、修正いたします。
(この記事は会社とは関係ありません)

WaiChan
フロントエンジニア バックエンドにチャレンジしてます スケートしてて足が折れるぐらいに体がおじいちゃんです。
negocia
「うれしい広告の実現へ」というミッションを掲げ、AIを活用した広告運用のSaaSツールの開発をしています。
https://negocia.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした