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

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

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

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

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

2回答

1040閲覧

RubyでSQL文のジェネレート処理をキレイに書くには?

angelica-k

総合スコア14

Ruby

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

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

0クリップ

投稿2017/08/22 10:27

###前提・実現したいこと
Ruby on Railsを使用して開発しています。
特定のカラムを初期値に設定するために、SQLを発行していますが、
同じ配列を複数回並べるなど、どうにも冗長な部分が多く感じています。
SQLの発行、発行結果の代入処理について、もっと合理的な書き方はあるでしょうか。

###該当のソースコード

ruby

1 def status_rollback 2 object_id = id 3 # 発行するSELECT文のターゲット 4 object_columns = [ 5 'DEFAULT(report)', 6 'DEFAULT(tag_1)', 7 'DEFAULT(tag_2)', 8 'DEFAULT(tag_3)', 9 'DEFAULT(tag_4)', 10 'DEFAULT(tag_5)', 11 'DEFAULT(attacked)'] 12 13 # SQLを発行 14 default_values = ActiveRecord::Base.connection.select_one( 15 "SELECT 16 #{object_columns[0]}, 17 #{object_columns[1]}, 18 #{object_columns[2]}, 19 #{object_columns[3]}, 20 #{object_columns[4]}, 21 #{object_columns[5]}, 22 #{object_columns[6]}, 23 #{object_columns[7]}, 24 FROM translations WHERE id = #{object_id};") 25 26 #値の反映 27 self.title = default_values[object_columns[0]] 28 self.report = default_values[object_columns[1]] 29 self.tag_1 = default_values[object_columns[2]] 30 self.tag_2 = default_values[object_columns[3]] 31 self.tag_3 = default_values[object_columns[4]] 32 self.tag_4 = default_values[object_columns[5]] 33 self.tag_5 = default_values[object_columns[6]] 34 self.attacked = default_values[object_columns[7]] 35 save! 36 end

###補足情報(言語/FW/ツール等のバージョンなど)
ruby 2.2.0p0 (2014-12-25 revision 49005)

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

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

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

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

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

guest

回答2

0

ベストアンサー

Model.newして得られるオブジェクトにはDBに設定されたデフォルト値が入っています。それをコピーしてやればよいです。

blank = Model.new %i(title report tag_1 ...).each {|col| self[col] = blank[col]}

投稿2017/08/22 15:10

suzukis

総合スコア1449

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

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

angelica-k

2017/08/23 00:43

ありがとうございます。おかげさまで10行未満で関数を実装することができました。 Model.newするとデフォルト値がとれるとは知りませんでした。 また、%記法というものもあるのですね。非常に勉強になりました。
guest

0

あまりよい書き方ではないかもしれませんが、以下はどうでしょうか。
配列の繰り返しの部分をなくす形で記載できればと考えてみました。
1点、object_columnsの最初にtitleが来るのかと思い追記していますが、間違っていたらごめんなさい。

Ruby

1 def status_rollback 2 object_id = id 3 4 # 発行するSELECT文のターゲット 5 object_columns = [ 6 'DEFAULT(title)', 7 'DEFAULT(report)', 8 'DEFAULT(tag_1)', 9 'DEFAULT(tag_2)', 10 'DEFAULT(tag_3)', 11 'DEFAULT(tag_4)', 12 'DEFAULT(tag_5)', 13 'DEFAULT(attacked)'] 14 15 # SQLを発行 16 default_values = ActiveRecord::Base.connection.select_one( 17 "SELECT " + object_columns.join(", ") + " FROM translations WHERE id = #{object_id};") 18 19 #値の反映 20 self.title, 21 self.report, 22 self.tag_1, 23 self.tag_2, 24 self.tag_3, 25 self.tag_4, 26 self.tag_5, 27 self.attacked = object_columns.map {|x| default_values[x]} 28 29 save! 30 end

また、SQL文の組み立てにはプリペアドステートメント等を利用すると安全にクエリ実行ができます。
こちらも調べてみられるとよいかと思います。

投稿2017/08/22 11:57

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

angelica-k

2017/08/23 00:41

ありがとうございます。 おっしゃる通り、titleが来る、であっております。 頭の片隅にはあったのですが、イテレータの使い方を思い出しました。 また、プリペアドステートメントについてご指摘いただきありがとうございます。 今後気をつけて実装していこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問