QA@IT

Ruby on Rails3においてモデルの属性値を数値として取得する方法について

3699 PV

質問失礼いたします。

表題の件について、現状はコントローラのアクションに

suuti_zokuseiti = model.scoped.pluck('カラム名')[0]

のように、まず配列を取得しそこから属性値を数値として取得するように書いているのですが、 他の方法で属性値を数値として取得する方法がありましたらご教示くださいますと幸いです。

どのような目的でこの方法を知りたいのかを簡単に説明いたしますと、

# 例1
postage = Postage.where(:area_id => area_id) # 送料レコードを取得
postage_price = postage.scoped.pluck('price')[0] # 送料レコードから送料を取得
total_postage_price = postage_price * quantity # 送料×数量で合計送料を算出

のように、モデルから取得した属性値を最終的に計算式にて利用するためです。

上記の例を例えば次のように書き換えてみると、

# 例2
postage_price = Postage.where(:area_id => area_id).select('price')
total_postage_price = postage_price * quantity

1行目がActiveRecord::Relationを返すため、それを2行目の計算式にて利用することができません。

そのため例1の2行目に記述した方法でFixnumとしてpostage_priceを取得し、属性値を計算式に利用している現状なのですが、もっとスッキリ書けないものかと疑問に思い質問させていただいております。

初歩的な質問で大変恐縮ですが、ご教示くださいますと幸いです。
よろしくお願いいたします。

version: Rails 3.2.13, ruby 1.9.3p194

【追記】sakuro様にいただいた回答の内容と関連して

2013/07/02 23:19

sakuro様にいただいた回答の内容と関連して、表題の件について二点疑問に思うことがありましたので追記いたします。

pluckを使わずにARインスタンス化を避ける方法はありますでしょうか?

②例2のようにARインスタンス化をした状態から、Fixnumの値を取得する方法はありますでしょうか?

こちらもあわせてご確認いただけますと幸いです。よろしくお願いいたします。

【追記】2013/07/02 23:19に追記した内容について

2013/09/14 10:41

質問当時はRailsを触りはじめたばかりであったため、何が分かっていないかが分かっていない状況で質問をしてしまっていました。

本来、質問したかったことを今の知識であらためて書いてみると「whereで取得したActiveRecord::Relationから、配列オブジェクトやモデルを取得する方法について」となります。

①whereで取得したActiveRecord::Relationから配列オブジェクトを取得する方法
pluckを用いて配列オブジェクトを取得することができます。

postage_record = Postage.where(:area_id => area_id) # 送料レコードを取得
postage_price  = postage_record.pluck('price')[0] # 送料を取得
total_postage_price = postage_price * quantity # 合計送料を算出

②whereで取得したActiveRecord::Relationからモデルを取得する方法
firstやlastを用いてモデルを取得することができます。

postage_record = Postage.where(:area_id => area_id) # 送料レコードを取得
postage_price  = postage_record.select('price').first # 送料を取得
total_postage_price = postage_price * quantity # 合計送料を算出

まだまだ綺麗な説明ができない理解ではありますが、sakuro様と他の閲覧者様に失礼のないよう現段階での理解を追記させていただきました。

回答

pluck を使ってARインスタンス化を避けつつ、よりシンプルに書きたいということですよね。

とりあえず、 where が Relation を返すので、 例1の scoped は要りません。
が、それ以上はシンプルにならないんじゃないかと思います。

[0] の代わりに first とか shift とか書いたところでかえって長くなりますし:)

編集 履歴 (0)
  • ご回答いただきありがとうございます。

    ご指摘いただいた通り、例1の scoped は不要ですね。ありがとうございます:)

    質問の趣旨について、例1にて私がpluckを使ったのは、まさにARインスタンス化を避けるためですので、「ARインスタンス化を避けつつ、よりシンプルに書きたいということ」ということで間違いありません。
    -
  • その点と関連して、二点疑問に思うことがありましたので、質問に追記させていただきました。

    お時間のございます際に、ご確認をお願い出来ますと幸いです。よろしくお願いいたします。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。