/ / Rails: як сортувати за розрахунковою різницею дат? - рубінові рельєфи, рельєфи-активні рекорди

Rails: як сортувати за розрахунковою різницею дат? - рубінові рельєфи, рельєфи-активні рекорди

У моєму моделі в мене є розраховане поле, як показано нижче.

class Products < ApplicationRecord
attr_reader :days

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

end

Коли я намагаюсь сортувати його, я отримую помилку.

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

Помилка:

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

Я буду вдячний, якщо хто-небудь зможе показати мені, як сортувати на основі розрахованого поля?

Відповіді:

1 для відповіді № 1

Рейки замовлення Параметр claum columb повинен існувати в таблиці, не підтримує призначений для користувача користувацький атрибут у моделі. Отже, ви повинні використовувати рубін сортувати за метод для спеціально визначених атрибутів, як показано нижче,

Product.all.sort_by(&:days)

Також вам доведеться змінити свій метод, як нижче,

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

Це буде просто працювати, але це не найкраща практика для сортування записів на основі спеціального користувацького атрибута. Отже, ви повинні перемістити цю логіку в сам запит sql, як показано нижче.

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

Він працює на postgres, не впевнений про mysql, будь ласка, перевірте альтернативу в mysql, якщо не працює.


1 для відповіді № 2

проблема для вашого коду вище - attr_reader: дні, тим часом дні ви оголошували як метод не змінний

ось моя ідея для вашої проблеми

у вашій моделі

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

у вашому контролері

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

1 для відповіді № 3

Я не знаю, як ви використовуєте цю частину коду:

(Date.today - self.created_at).to_i

Оскільки він очікує числове значення з - знак Я зміг це зробити так:

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

Але головне - я думаю, ви хочете замовити записи created_at дата. Тому за замовчуванням він зростає, і ви хочете відобразити записи, які були створені нещодавно, щоб ви могли зробити це прямо так:

Product.all.order(:created_at)

і якщо ви хочете, щоб це в порядку спаду, то ви можете зробити це так:

Product.all.order(created_at: :desc)

Тим не менш, якщо вам потрібно sort це за допомогою attr_reader інші відповіді показують, як це можна зробити. Просто питання полягає в тому, що pagination працює на ActiveRecord::Collection а не масив так для will_paginate Ви можете вказати тут:

Ruby on Rails will_paginate масив

Сподіваюся, це допоможе.