Rails ActiveRecord find_by_sql呼び出しの結果の列順序
-
03-07-2019 - |
質問
基本的なレポート画面をまとめようとしています。 ActiveRecordのfind_by_sqlメソッドにフィードするかなり複雑なSQLクエリがあります。ここでの問題は、元のクエリで指定された列の順序が失われていることです。これは、Hashクラスがキーの入力順序を保持しないためだと考えています。
この問題を回避する方法はありますか?クエリにfind_by_sqlと異なる方法を使用する必要がありますか?
解決
Rubyハッシュは順序を保持しないという点であなたは正しいです。それはポイントの一部です、本当に-あなたはキーを使用してそれにアクセスします。
列を出力する順序で配信するようにクエリが記述されており、ループ経由で値を出力することを望んでいましたか?まともなアイデアのように思えますが、少なくともいくつかの追加作業なしでそれを達成する方法は考えられません。
テンプレートのキーで列に明示的にアクセスすることをお勧めします。おそらく、スタイルを適用し、number_with_delimiterなどのヘルパー関数を使用して書式設定することになります。
上記のショートカットのようなものを取得するには、必要な順序でシンボルの配列を作成し、ループ内のハッシュから値を引き出すことができると思います。このようなもの? (潜在的に危険なエラーを言い訳してください:私は haml ユーザーです!)
<% for row in @report.rows %>
<tr>
<% for col in [:a, :b, :c] %>
<td><%= row[col] %></td>
<% end %>
</tr>
<% end %>
他のヒント
レポートには Ruport を使用します。 ActiveRecordとの統合が良好であり、列の順序などを制御できます。そして、それは使用するのが十分に簡単なので、「基本」であってもそれが過剰だとは思わない。レポート。
rails 3.2以降では、 find_by_sql
の結果の各レコードに対して attribute_names
を使用できます。
これは、 find_by_sql :
データベースに対してカスタムSQLクエリを実行し、すべての 結果。結果は列を持つ配列として返されます このメソッドを呼び出すモデルの属性としてカプセル化された要求 から。
Product.find_by_sql
を呼び出すと、結果は で指定した属性を持つProduct
オブジェクトで返されます SQLクエリ。複数のテーブルにまたがる複雑なSQLクエリを呼び出す場合、 SELECTで指定された列はモデルの属性になり、 対応するテーブルの列であるかどうか
モデルの場合、column_namesを使用できます。バリエーションの詳細については、他のSAの回答をご覧ください:モデルを見つける方法Railsの属性
これらの「レポート画面」をどのように作成していますか?それらはerbテンプレートですか?列で.eachを呼び出してそれらをすべて出力しますか?
その場合、モデル内のcolumns()メソッドをオーバーライドして、順序付けられた配列を返すことができます。