質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

1回答

1460閲覧

大量のレコードの数値型カラムの現在の値に加算して、一括更新したい

zendendo

総合スコア43

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2017/12/22 12:40

編集2017/12/24 23:19

###前提・実現したいこと
ruby(rails)で、数量(口座残高)を扱う口座モデル(Account)をつくり、
一部の例外な口座を除き、ほぼ全ての口座残高を更新したいと考えています。

例えば、
Account(口座モデル)のidが19番(例外な口座)以外の口座レコードを取得して、
取得した口座達の残高(balanceカラム)に対して+1000を加算する一括更新をしたいとします。

Account.where.not(id: 19).update_all(balance: 1000)と記述することで
例外(この場合は、Accountのidが19のレコード)を除いた
口座群を取得して、
残高(balance)を数値1000に書き換えて
一括更新できることはわかったのですが、
この場合、現状の残高を無視して全ての残高が1000になってしまいます。

Account.where.notで取得した多数の口座(Accountモデルのレコード)の残高(数値型のカラム)に対してたし算をして一括更新をしたいのですが、
どうすればいいのか教えて頂ければ幸いです。

以下は現状のコードです。

begin ActiveRecord::Base.transaction{ Account.where.not(id: 19).update_all(balance: Account.where.not(id: 19).balance+ 1000) } end

###補足情報(言語/FW/ツール等のバージョンなど)
Rails 5.1.3
ruby 2.4.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ruby

1 Account.where.not(id: 19).update_all("balance = balance + 1000")

でどうでしょうか?

投稿2017/12/23 13:47

togino77

総合スコア143

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zendendo

2017/12/24 12:00 編集

togino77さん、回答ありがとうございます。 アドバイス通りのコードで解決することができました。 ちょっと気になったことがあったのですが、 ダブルクォートで囲った部分は文字列型の情報として扱うときに使われるものだと聞いたのですが、なぜ今回はダブルクォートでかこっても文字列としてではなく数値として処理することができたのでしょうか?
togino77

2017/12/24 13:06

SQLという言語をご存知でしょうか?Railsではモデルにおける find(選択),create(追加),update(更新),destroy(削除) などの処理はSQLに変換されてから、SQLiteやMySQLで実行されます。 通常はSQLを意識しないでもすむように設計されているのですが、今回のケースでは、SQLを直接書いた方がシンプルかと思い、update_all に実行してほしい内容をSQLで指定しました。 SQLはテキストで表現されるため文字列になります。その文字列がMySQLなどで構文解析されて実行される訳です。 つまり update_all に渡した"balance=balance+1000"は、Ruby言語の世界における文字列であり、MySQLで実行される際には balance=balance+1000というSQL言語の世界における数式と解釈されます。なので1000は数値です。 なので、SQLで文字列を扱いたい場合は、update_all("name='alice'") のようにRubyからすると文字列の中に文字列があるように見えます。 もっとも、この場合 update_all(name: "alice") のようにSQLなんかを書くことはなく、RailsにSQLの生成を任せるのがよいでしょう。なぜなら、SQLには方言があるので、直接書くと汎用性が失われるからです。
zendendo

2017/12/24 23:15

rails(ruby)のコードの中で、SQLとして書いてあるからダブルクォートでも数値として処理されるのですね。詳しい解説ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問