/ / Rails: come ordinare in base alla differenza di data calcolata? - ruby-on-rails, rails-activerecord

Rails: come ordinare in base alla differenza di data calcolata? - ruby-on-rails, rails-activerecord

Ho un campo calcolato nel mio modello come segue.

class Products < ApplicationRecord
attr_reader :days

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

end

Quando provo ad ordinarlo, ricevo un errore.

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

Errore:

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

Apprezzerò se qualcuno mi può mostrare come ordinare in base a un campo calcolato?

risposte:

1 per risposta № 1

Rails ordine il parametro clausola columb dovrebbe esistere nella tabella, non supporta l'attributo personalizzato definito dall'utente nel modello. Quindi, devi usare il rubino ordina per metodo per attributi definiti personalizzati come di seguito,

Product.all.sort_by(&:days)

E inoltre devi cambiare il tuo metodo per piacere di seguito,

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

Funzionerà ma questa non è una procedura ottimale per ordinare i record in base all'attributo personalizzato definito dall'utente. Quindi, devi spostare questa logica in sql query stessa come di seguito,

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

Funziona su postgres, non sono sicuro di mysql, per favore controlla alternativamente in mysql se non funziona.


1 per risposta № 2

il problema per il tuo codice sopra è attr_reader: days, intanto i giorni che hai dichiarato come metodo non variabile

ecco la mia idea per il tuo problema

nel tuo modello

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

nel tuo controller

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

1 per risposta № 3

Non sono sicuro di come si sta eseguendo questo pezzo di codice:

(Date.today - self.created_at).to_i

Perché si aspetta un valore numerico con il - cartello. Sono stato in grado di farlo in questo modo:

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

Ma il punto principale è che penso tu voglia ordinare i dischi created_at Data. Quindi per impostazione predefinita è crescente e vuoi visualizzare i record che sono stati creati di recente per primi in modo che tu possa farlo in questo modo direttamente:

Product.all.order(:created_at)

e se lo vuoi in ordine decrescente puoi farlo in questo modo:

Product.all.order(created_at: :desc)

Comunque se è necessario sort da un attr_reader le altre risposte mostrano come puoi farlo. Solo il problema sarà che il pagination funziona ActiveRecord::Collection piuttosto che array così per will_paginate puoi fare riferimento qui:

Ruby on Rails will_paginate un array

Spero che questo ti aiuti.