Techioz Blog

エイリアスを持つ ActiveRecord グループ

概要

ここでの最初の質問ですが、完全なアプリ/Rails のコーディングに関してはかなり初心者です。

著者ごとにタイトルの数を取得するメソッドを作成していましたが、著者の大文字と小文字が異なる場合、別の著者としてカウントされることに気付きました。大文字と小文字を無視して一緒にカウントするために、ある種の検証/チェックを配置したかったのです。この特定の場合、本のタイトルの大文字と小文字は気にしません。

したがって、次のようなテーブルがあります。

Author                Book Title                               Year    Condition
William Shakespeare   Hamlet                                   1599    Poor
Stephen King          The Shining                              1977    New
Edgar Allen Poe       The Raven                                1845    Good
JK Rowling            Harry Potter and the Sorcerer's Stone    2001    New
edgar allen poe       The Tell-Tale Heart                      1843    Good
JK Rowling            Fantastic Beasts and Where to Find Them  2001    New

これを出力したいのですが:

Author                 Count
William Shakespeare    1
Stephen King           1
Edgar Allen Poe        2                              
JK Rowling             2 

私の方法はもともと次のようなものでした。

  def self.book_counts
    distinct_counts = []
    Book.group(:author).count.each do |count|
      distinct_counts << count
    end
    distinct_counts
  end

大文字と小文字を無視するために、このページを参照して次のことを思いつきましたが、残念ながら最終的にはうまくいきませんでした。

1)これを使用すると、「未定義のメソッドが下位になります」となります。

    Book.group(lower('author')).count.each do |count|
      distinct_counts << count
  1. これは実行されますが、一般に select メソッドを使用すると、大量の ActiveRecord 結果/レコード ID: nil が取得されます。 Rails 6を使用していますが、さらに「非推奨の警告: 危険なクエリメソッド(引数が生のSQLとして使用されるメソッド)が非属性引数で呼び出されています…非属性引数はRails 6.1では許可されません。これはメソッドは、リクエスト パラメーターやモデル属性などのユーザー指定の値を使用して呼び出すことはできません。既知の安全な値は、Arel.sql() でラップすることで渡すことができます ((irb):579 の irb_binding から呼び出されます)。
Book.select("lower(author) as dc_auth, count(*) as book_count").group("dc_auth").order("book_count desc")
  1. 別の単純化された関数をテストして、それが機能するかどうかを確認しようとしましたが、「ActiveRecord::StatementInvalid (PG::GroupingError: ERROR: 列 “books.author” は GROUP BY 句に表示する必要があります。または集計関数で使用できます)“:
    Book.pluck('lower(author) as dc_auth, count(*) as book_count')
  1. 他のさまざまな方法を試しましたが、さらに別のエラーが発生しました。 「未定義のローカル変数またはメソッド ‘dc_auth’」、「未定義のメソッド ‘group’ は group_by のことですか?」、および「引数の数が間違っています (1 が指定され、0 が期待されます)」 (group_by を使用) など。

このクエリは、postgresql で希望どおりに機能します。 #2 を実行すると、実際には構文がターミナルに入力されますが、前述したように、残念ながら ActiveRecord のせいで、Rails では正しく出力されません。

SELECT lower(author) as dc_auth, count(*) as book_count FROM books GROUP BY dc_auth;

Rails を介して必要なものを実行する方法はありますか??

解決策

試してみてもいいかもしれません

Book.group("LOWER(author)").count