Gestione dei rapporti bambino con un modulo di attributo nidificato
-
11-09-2019 - |
Domanda
Quello che sto cercando di fare è la seguente:
Al momento chiunque un utente può avere 1 profilo attivo. Questo profilo attivo deve essere autorizzato da un amministratore per assicurarsi che sia compatibile con le norme ei regolamenti del sito. Quando un utente modifica il loro profilo il loro profilo pubblico non è influenzato finché l'amministratore firma i loro cambiamenti. Se fanno una modifica, mentre il loro profilo è in revisione, le loro modifiche vengono applicate al profilo in sospeso per la revisione e viene spinto verso la parte posteriore della coda.
I miei modelli sono qualcosa del tipo:
class Profile < AR:B
belongs_to :user
end
class User < AR:B
has_many :profiles do
def active
...
end
def latest
end
end
def profile
self.profiles.active
end
end
C'è una piccola torsione ... l'utente non dovrebbe essere in grado di modificare il profilo direttamente, come la raccolta di profili non è esposto. Invece modificare il loro utilizzo ed il campi del profilo vengono mostrati lì.
Qual è il modo migliore per gestire questo? Attualmente sto usando:
accepts_nested_attributes_for :profiles
l'utente, ma che sembra abbastanza hacky. Idealmente la maggior parte di questa logica sarebbe vissuto nel modello, ma l'altra cosa che sto flirtando con è l'uso di un presentatore.
Ogni pensiero sarebbe molto apprezzato, fatemi sapere se avete bisogno di più informazioni, come un commento e io aggiornare questo post in modo appropriato.
Soluzione
Forse si dovrebbe cercare di avere due rapporti da utente al profilo. Una è quella che possono modificare attraverso l'interfaccia utente, e l'altro è quello che è approvato dall'amministratore.
Potrebbe funzionare qualcosa come:
class User < AB:B
has_one :profile #the user-editable one one
has_one :active_profile, :class_name=>"profile" #the one shown
end
Ogni modifica sul profilo utente tramite il modulo sarebbe poi mostrare per l'amministrazione (usando ed osservatore o forse solo e "after_save" filtro). Quando aproves essa, le modifiche vengono poi scaricati al active_profile uno, e mostrati da qualche parte.
In questo modo, si può avere un interfaccia di forma pulita, e ogni volta che modifica di nuovo, si veda l'ultimo (ma non approvata) profilo. È inoltre possibile ordinare la coda utilizzando la colonna updated_at per ottenere i "loro modifiche vengono applicate al profilo in sospeso per la revisione e viene spinto verso la parte posteriore della coda" funcionality.
Altri suggerimenti
Mi piacerebbe andare su questo avendo il modello utente hanno un rapporto con due profili come suggerito sopra pure. Un "Approvato" profilo, e quello per la modifica che va nella vostra coda di amministrazione.
Tuttavia, al fine di gestire le transizioni tra i profili "in sospeso" e "approvate" profili Io suggerirei aggiungendo eventualmente in una macchina a stati per gestire le transizioni. La gemma SAMA è stato buono per me in un recente progetto. ( http://github.com/rubyist/aasm/tree/master ), e credo bordo Rails ha appena sfornato proprio Stato Machinage in pure. ( http://github.com/rails/rails/commit/aad5a30bf25d8a3167afd685fc91c99f4f09cc57 )
Il tuo modello potrebbe essere simile a questa:
class User < AR:B
has_one :active_profile
has_one :pending_profile
include ActiveRecord:: StateMachine
state_machine do
state :approved
state :pending
state :rejected
event :update_profile_pending do
transitions :to => :pending, :from => [:approved], :on_transition => :send_to_admin_queue
end
event :update_profile_approved do
transitions :to => :approved, :from => [:pending], :on_transition => :update_current_profile
end
event :update_to_rejected do
transitions :to => :rejected, :from => [:pending]
end
end
def send_to_admin_queue
//method to handlesending pending profiles to admin for approval
end
def update_current_profile
//method to handle updated profiles with changes
end
end
È quindi possibile chiamare profilo User.update in attesa! o profilo User.update approvato! per la transizione tra il tuo profilo stati e utilizzare i callback di transizione per gestire l'invio dei dati di modifica tra il vostro profilo attivo e in attesa di profilo.
Per quanto riguarda utilizzando il nested_attributes_for con il modulo attuale, non credo che sia un hack, ho usato anche per aggiornare gli attributi nidificati e piacerebbe lavorare bene. In questo caso però potrebbe non essere necessario troppo dal momento che si hanno 2 profili (uno pubblico, uno in sospeso).
Solo un'idea! Pensando ad alta voce qui!