Implementazione di un ActiveRecord before_find
-
03-07-2019 - |
Domanda
Sto creando una ricerca con le parole chiave memorizzate nella cache in una tabella. Prima che una parola chiave immessa dall'utente venga cercata nella tabella, viene normalizzata. Ad esempio, alcuni segni di punteggiatura come "-" vengono rimossi e l'involucro è standardizzato. La parola chiave normalizzata viene quindi utilizzata per trovare recuperare i risultati della ricerca.
Attualmente sto gestendo la normalizzazione nel controller con un filtro pre-filtro. Mi chiedevo invece se ci fosse un modo per farlo nel modello. Qualcosa di concettualmente simile a un " before_find " il callback funzionerebbe anche se non avrebbe senso per un livello di istanza.
Soluzione
Dovresti usare ambiti denominati:
class Whatever < ActiveRecord::Base
named_scope :search, lambda {|*keywords|
{:conditions => {:keyword => normalize_keywords(keywords)}}}
def self.normalize_keywords(keywords)
# Work your magic here
end
end
L'uso degli ambiti denominati ti consentirà di concatenare altri ambiti ed è davvero il modo di andare usando Rails 3.
Altri suggerimenti
Probabilmente non vorrai implementarlo sostituendo find. Sostituire qualcosa come find sarà probabilmente un mal di testa lungo la linea.
Potresti creare un metodo di classe che fa quello che ti serve, qualcosa come:
class MyTable < ActiveRecord::Base
def self.find_using_dirty_keywords(*args)
#Cleanup input
#Call to actual find
end
end
Se veramente vuoi sovraccaricare, puoi farlo in questo modo:
Ad esempio:
class MyTable < ActiveRecord::Base
def self.find(*args)
#work your magic here
super(args,you,want,to,pass)
end
end
Per ulteriori informazioni sulla sottoclasse, consulta questo link: Ruby Tips
proprio come sopra, puoi anche usare un alias_method_chain
.
class YourModel < ActiveRecord::Base
class << self
def find_with_condition_cleansing(*args)
#modify your args
find_without_condition_cleansing(*args)
end
alias_method_chain :find, :condition_cleansing
end
end