ruby 具有别名的ActiveRecord组

rwqw0loc  于 2023-11-18  发布在  Ruby
关注(0)|答案(3)|浏览(92)

第一个问题是在这里,和相当新的编码完整的应用程序/Rails。
我创建了一个方法来按作者获取书名的计数,并注意到如果作者的大小写不同,它将被视为不同的作者。我想放置某种验证/检查来忽略大小写并一起计数。在这种特殊情况下,我不关心书名的大小写。
我有一张这样的table:

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


为了忽略大小写,我引用了this page并提出了这些,不幸的是,这些最终没有成功:
1)使用这个方法,我得到了“undefined方法更低”:

Book.group(lower('author')).count.each do |count|
      distinct_counts << count


2)这会运行,但是一般来说,使用select方法,我会得到一堆ActiveRecord结果/Record id:nil。我使用Rails 6,它另外注明了“DEPRECATION”:危险查询方法(其参数用作原始SQL的方法)使用非属性参数调用. Rails 6.1中不允许使用非属性参数。此方法不应使用用户提供的值调用,例如请求参数或模型属性。已知安全的值可以通过将它们 Package 在Arel.sql()中来传递。(从irb_binding at(irb):579调用)":

Book.select("lower(author) as dc_auth, count(*) as book_count").group("dc_auth").order("book_count desc")


3)我甚至试着测试一个不同的简化函数,看看它是否能工作,但我得到了“ActiveRecord::StatementInvalid(PG::GroupingError:ERROR:column“books.author“must appear in the GROUP BY clause or be used in an aggregate function)":

Book.pluck('lower(author) as dc_auth, count(*) as book_count')


4)我尝试过其他各种方法,但都有其他不同的错误,例如“undefined local variable or method 'dc_auth'”、“undefined method 'group' did you mean group_by?"和“wrong number of arguments(given 1,expected 0)”(with group_by)等。
这个查询在postgresql中完全按照我想要的方式工作。当我运行#2时,语法实际上在终端中填充,但正如前面提到的,不幸的是,由于ActiveRecord在Rails中不能正确输出。

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


有没有一种方法可以通过Rails运行我想要的东西?

6vl6ewon

6vl6ewon1#

也许你可以试

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

字符串

eagi6jfj

eagi6jfj2#

你可以使用ActiveRecord来执行你的查询。我建议你使用SQL块

book_count_query = <<-SQL 
       SELECT lower(author) as dc_auth, count(*) as book_count
       FROM books
       GROUP BY dc_auth;
SQL

1- result = ActiveRecord::Base.connection.execute(book_count_query)

or 
2- result = ActiveRecord::Base.connection.exec_query(book_count_query)

字符串

1号线和2号线有什么区别?

exec_query它返回一个ActiveRecords::Result对象,该对象具有.columns.rows等方便的方法来访问头和值。
来自.execute的哈希数组处理起来可能很麻烦,当我运行SUM GROUP BY子句时,它会给我冗余的结果。
如果你需要阅读更多关于这个主题

x6yk4ghg

x6yk4ghg3#

为什么要将作者和书籍存储在同一个表中。更好的解决方案是为作者添加一个单独的表,并在author_idbooks表中添加一个外键。使用counter_cache,您可以轻松计算每个作者的书籍数量。
以下是booksauthors示例https://guides.rubyonrails.org/association_basics.html的指南

相关问题