我正在構建一個Rails應用程式,其模型如下:
我正在構建一個Rails應用程式,其模型如下:
# vote.rb
class Vote < ApplicationRecord
belongs_to :person
belongs_to :show
scope :fulfilled, -> { where(fulfilled: true) }
scope :unfulfilled, -> { where(fulfilled: false) }
end
# person.rb
class Person < ApplicationRecord
has_many :votes, dependent::destroy
def self.order_by_votes(show = nil)
count = 'nullif(votes.fulilled, true)'。
count = "case when votes.show_id = #{show.id} AND NOT votes.filled then 1 else null end" if show
people = left_joins(:votes).group(:id).uniq! (:group)
people = people.select("people.*, COUNT(#{count}) AS people.vote_count"/span>)
people.order('people.vote_count DESC'/span>)
結束。
結束。
order_by_votes背后的想法是根據未完成的投票數對People進行排序,要么計算所有的投票,要么只計算與特定Show相關的投票。
當我用SQLite測驗時,這似乎可以正常作業。但當我切換到Postgres時,我得到了這個錯誤:
Error。
PeopleControllerIndexTest#test_should_get_previously_on_show:。
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column people.vote_count does not exist
行 1: ...s". "show_id" = $1 GROUP BY "people"id" ORDER BY people.vot...
如果我使用@people.to_sql轉儲SQL,我得到的結果是:
SELECT people.*, COUNT(nullif(votes.fulilled, true)) AS people.vote_count FROM "people" LEFT OUTER JOIN "votes" ON "votes". "person_id" = "people". "id" GROUP BY "people". "id" ORDER BY people.vote_count DESC
為什么在Postgres上會失敗,而在SQLite上卻能作業?我應該怎么做才能讓它在Postgres上運行呢?
(PS: 我將欄位命名為people.vote_count,并加了一個點,這樣我就可以在我的視圖中訪問它,而不需要進行另一個SQL查詢來實際查看視圖中每個人的投票數(不確定這是否有效),但是即使我將欄位簡單命名為vote_count,我也會得到相同的錯誤。
(PS2: 我最近添加了.uniq!(:group),因為Rails 6.2的一些棄用警告,但我找不到任何相關的檔案,所以我不確定我是否做對了,沒有這部分,錯誤仍然存在。
uj5u.com熱心網友回復:
你確定你沒有從PostgreSQL的某個地方得到一個語法錯誤?如果你做這樣的事情:
select count(*) as t.vote_count from t ... order by t.vote_count
在PostgreSQL抱怨沒有t.vote_count列之前,我得到一個語法錯誤。
沒關系,解決辦法是不要試圖把你的vote_count放在people表中:
people = people.select("people.*, COUNT(#{count}) AS vote_count" )
...
people.order(vote_count: :desc).
你不需要它,你仍然能夠參考vote_count,就像people中的任何 "正常 "列。選擇串列中的任何內容都將作為訪問器出現在結果模型實體中,無論它們是否是列,它們都不會出現在#inspect輸出中(因為那是基于表的列生成的),但你還是要呼叫訪問器方法。
uj5u.com熱心網友回復:
從歷史上看,有不少AR問題(和bug),通過在范圍上使用count來獲得正確的計數,我不確定它們是否真的都消失了。
這取決于范圍(AR版本、關系、組、排序、uniq等)。一個defaut count 呼叫,一個 gem 必須在一個作用域上通用地使用,這不是一個萬能的解決方案。出于這個已知的原因,Pagy允許你將正確的計數傳遞給它的pagy方法,正如在Pagy檔案中所解釋的。
你的范圍可能會變得復雜,默認的pagy
collection.count(:all)可能無法獲得實際的計數。在這種情況下,你可以通過一些自定義陳述句獲得正確的計數,并將其傳遞給pagy。
@pagy, @records = pagy(collection, count: your_count)
注意:pagy將有效地跳過其內部的計數查詢,而只是使用傳遞的
:count變數。
所以......只要得到你自己計算的計數并將其傳遞給pagy,它甚至不會嘗試使用默認值。
編輯:我忘了說:你可能想試試pagy arel extra那個:
通過使用
COUNT(*) OVER ()計算結果的總數,為帶有GROUP BY子句的sql資料庫的集合添加專門的分頁。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/334291.html
標籤:
