/ / Rails: jak sortować według obliczonej różnicy daty? - ruby-on-rails, rails-activerecord

Railsy: jak sortować według obliczonej różnicy daty? - ruby-on-rails, rails-activerecord

Mam pole obliczone w moim modelu w następujący sposób.

class Products < ApplicationRecord
attr_reader :days

def days
(Date.today - self.created_at).to_i
end

end

Kiedy próbuję to posortować, pojawia się błąd.

@products = Product.all.order("days").paginate(:page => params[:page], :per_page => 15)

Błąd:

PG::UndefinedColumn: ERROR:  column "days" does not exist

Będę wdzięczny, jeśli ktoś może pokazać mi, jak sortować na podstawie pola obliczeniowego?

Odpowiedzi:

1 dla odpowiedzi № 1

Szyny zamówienie znacznik parametru klauzuli powinien istnieć w tabeli, nie obsługuje niestandardowego atrybutu zdefiniowanego przez użytkownika w modelu. Więc musisz użyć rubinu Sortuj według metoda dla niestandardowych zdefiniowanych atrybutów, takich jak poniższe,

Product.all.sort_by(&:days)

Musisz także zmienić metodę, tak jak poniżej,

def days
DateTime.now.to_i - self.created_at.to_i
end

Po prostu działa, ale nie jest to najlepsza praktyka do sortowania rekordów na podstawie niestandardowego niestandardowego atrybutu zdefiniowanego przez użytkownika. Tak więc, musisz przenieść tę logikę do zapytania sql, jak poniżej,

Product.all.order("now() - created_at")

Działa na postgresie, nie jestem pewien co do mysql, proszę sprawdź alternatywę w mysql, jeśli nie działa.


1 dla odpowiedzi nr 2

problem z powyższym kodem to attr_reader: dni, w międzyczasie dni zadeklarowane jako metoda nie zmienna

oto mój pomysł na twój problem

w twoim modelu

class Products < ApplicationRecord

def total_days
(Date.today - self.created_at).to_i
end

def self.sorted_by_days
Product.all.sort_by(&:total_days).reverse
# just delete .reverse incase you want ascending
# I put reverse in case you want to sort descending
end

end

w twoim kontrolerze

@products = Product.sorted_by_days.paginate(:page => params[:page], :per_page => 15)

1 dla odpowiedzi nr 3

Nie jestem pewien, w jaki sposób uruchamiasz ten fragment kodu:

(Date.today - self.created_at).to_i

Ponieważ oczekuje wartości numerycznej z - znak. Udało mi się to zrobić tak:

((Time.zone.now - self.created_at) / 1.day).to_i

Ale najważniejsze jest to, że chciałbym zamówić te zapisy created_at data. Domyślnie jest to rosnąco i chcesz wyświetlić rekordy, które zostały ostatnio utworzone, dzięki czemu możesz zrobić to tak bezpośrednio:

Product.all.order(:created_at)

a jeśli chcesz to w porządku malejącym, możesz to zrobić tak:

Product.all.order(created_at: :desc)

Nadal, jeśli musisz sort to przez attr_reader pozostałe odpowiedzi pokazują, jak możesz to zrobić. Problem polega tylko na tym, że pagination działa dalej ActiveRecord::Collection zamiast tablic, więc dla will_paginate możesz polecić tutaj:

Ruby on Rails będzie_paginować tablicę

Mam nadzieję że to pomoże.