In Ruby on Rails Development (o MVC in generale), quale regola veloce dovrei seguire su dove mettere la logica.
Per favore, rispondi affermativamente: con Do metti questo qui , invece di non metterlo lì .
In Ruby on Rails Development (o MVC in generale), quale regola veloce dovrei seguire su dove mettere la logica.
Per favore, rispondi affermativamente: con Do metti questo qui , invece di non metterlo lì .
Risposte:
MVC
Controller : inserisci qui il codice che ha a che fare con l'elaborazione di ciò che un utente desidera e la decisione su cosa fornire, capire se sono connessi, se devono vedere determinati dati, ecc. Alla fine, il controller esamina le richieste e stabilisce quali dati (modelli) mostrare e quali viste visualizzare. In caso di dubbi sul fatto che il codice debba essere inserito nel controller, probabilmente non dovrebbe esserlo. Mantieni i tuoi controller magri .
Vista : la vista deve contenere solo il codice minimo per visualizzare i tuoi dati (modello), non dovrebbe eseguire molte elaborazioni o calcoli, dovrebbe mostrare i dati calcolati (o riepilogati) dal modello o generati dal controller. Se il tuo View ha davvero bisogno di eseguire elaborazioni che non possono essere eseguite dal Modello o dal Controller, inserisci il codice in un Helper. Un sacco di codice Ruby in una vista rende difficile il markup delle pagine.
Modello : il tuo modello dovrebbe essere dove risiede tutto il tuo codice relativo ai tuoi dati (le entità che compongono il tuo sito, ad esempio Utenti, Posta, Account, Amici ecc.). Se il codice deve salvare, aggiornare o riepilogare i dati relativi alle tue entità, inseriscili qui. Sarà riutilizzabile su viste e controller.
Per aggiungere alla risposta di Pauliephonic:
Helper : funzioni per facilitare la creazione della vista. Ad esempio, se stai sempre iterando su un elenco di widget per visualizzare il loro prezzo, inseriscilo in un aiuto (insieme a un parziale per la visualizzazione effettiva). O se hai un pezzo di RJS che non vuoi ingombrare la vista, mettilo in un aiuto.
Il modello MVC riguarda davvero solo l'interfaccia utente e nient'altro. Non è necessario inserire alcuna logica aziendale complessa nel controller poiché controlla la vista ma non la logica. Il Titolare dovrebbe occuparsi della selezione della vista corretta e delegare elementi più complessi al modello di dominio (Modello) o al livello aziendale.
Domain Driven Design ha un concetto di servizi che è un luogo in cui si attacca la logica che deve orchestrare una serie di vari tipi di oggetti, il che significa generalmente logica che non appartiene naturalmente a una classe Model.
In genere penso al livello di servizio come all'API delle mie applicazioni. I livelli dei miei servizi di solito si associano abbastanza da vicino ai requisiti dell'applicazione che sto creando, quindi il livello di servizio agisce come una semplificazione delle interazioni più complesse rilevate nei livelli inferiori della mia app, vale a dire che potresti raggiungere lo stesso obiettivo bypassando i livelli di servizio ma dovresti tirare molte più leve per farlo funzionare.
Nota che non sto parlando di Rails qui sto parlando di uno stile architettonico generale che affronta il tuo problema particolare.
Spiegazioni perfette qui già, una frase molto semplice come conclusione e facile da ricordare:
Abbiamo bisogno di modelli SMART, controller THIN e viste DUMB.
Il modo in cui Rails è avere controller skinny e modelli fat .
Inserisci elementi relativi al controllo di autorizzazione / accesso nel controller.
I modelli riguardano tutti i tuoi dati. Convalida, relazioni, CRUD, business logic
Le visualizzazioni riguardano la visualizzazione dei dati. Visualizza e ottieni solo input.
I controllori riguardano il controllo di quali dati vanno dal modello alla vista (e quale vista) e dalla vista al modello. I controller possono esistere anche senza modelli.
Mi piace pensare al controller come a un addetto alla sicurezza / receptionist che ti indirizza il cliente (richiesta) allo sportello appropriato dove fai una domanda a un cassiere (visualizza). Il cassiere (visualizza) quindi va e ottiene la risposta da un manager (modello), che non vedi mai. La richiesta quindi torna alla guardia giurata / addetto alla reception (controller) e attendi fino a quando non viene indirizzato a un altro cassiere (visualizza) che ti dice la risposta che il direttore (modello) ha detto loro in risposta alla domanda dell'altra cassiere (visualizza) .
Allo stesso modo, se vuoi dire qualcosa al cassiere (visualizza), allora succede la stessa cosa, tranne che il secondo cassiere ti dirà se il gestore ha accettato le tue informazioni. È anche possibile che la guardia di sicurezza / centralinista (responsabile del trattamento) ti abbia detto di fare un'escursione poiché non eri autorizzato a comunicare al gestore tali informazioni.
Quindi, per estendere la metafora, nel mio mondo stereotipato e irrealistico, i narratori (opinioni) sono carini ma a testa vuota e spesso credono a tutto ciò che dici loro, gli addetti alla sicurezza / receptionist sono minimamente educati ma non sono molto ben informati ma sanno dove le persone dovrebbero e non dovrebbe andare ei manager sono davvero brutti e cattivi, ma sanno tutto e possono dire cosa è vero e cosa non lo è.
Una cosa che aiuta a separare correttamente è evitare l'anti-pattern "passa variabili locali dal controller per visualizzare". Invece di questo:
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
def show
@foo = Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...
Prova a spostarlo su un getter disponibile come metodo di supporto:
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
helper_method :foo
def show
end
protected
def foo
@foo ||= Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...
Ciò semplifica la modifica di ciò che viene inserito in "@foo" e di come viene utilizzato. Aumenta la separazione tra controller e vista senza renderli più complicati.
foo
e di @foo
sono gli stessi - entrambi sono ambiti alla coppia <ControllerClass, request>. Inoltre, utilizzando la versione getter, posso cambiare il modo in cui l' Foo
oggetto viene trovato / memorizzato / memorizzato nella cache senza cambiare la modalità di accesso alla vista.
Beh, dipende in qualche modo da ciò che la logica ha a che fare con ...
Spesso ha senso spingere più cose nei tuoi modelli, lasciando i controller piccoli. Ciò garantisce che questa logica possa essere facilmente utilizzata da qualsiasi luogo sia necessario per accedere ai dati rappresentati dal modello. Le viste non dovrebbero contenere quasi nessuna logica. Quindi davvero, in generale, dovresti sforzarti di farlo in modo da non ripetere te stesso.
Inoltre, un breve pezzo di google rivela alcuni esempi più concreti di ciò che va dove.
Modello: requisiti di convalida, relazioni con i dati, creazione di metodi, aggiornamento di metodi, distruzione di metodi, ricerca di metodi (notare che non si dovrebbero avere solo le versioni generiche di questi metodi, ma se c'è qualcosa che si sta facendo molto, come trovare persone con il rosso capelli per cognome, quindi dovresti estrarre quella logica in modo che tutto ciò che devi fare è chiamare find_redH_by_name ("smith") o qualcosa del genere)
Visualizza: questo dovrebbe riguardare la formattazione dei dati, non l'elaborazione dei dati.
Controller: qui è dove va il trattamento dei dati. Da Internet: "Lo scopo del responsabile del trattamento è rispondere all'azione richiesta dall'utente, prendere tutti i parametri impostati dall'utente, elaborare i dati, interagire con il modello e quindi passare i dati richiesti, in forma finale, al Visualizza."
Spero che aiuti.
In termini semplici, generalmente, i Modelli avranno tutti i codici relativi alle tabelle, alle loro relazioni semplici o complesse (pensali come query sql che coinvolgono più tabelle), manipolazione dei dati / variabili per arrivare a un risultato usando la logica aziendale .
I controller avranno codice / puntatori verso i modelli rilevanti per il lavoro richiesto.
Le viste accettano l'input / interazione dell'utente e visualizzano la risposta risultante.
Qualsiasi grande deviazione da questi metterà a dura prova quella parte e le prestazioni complessive dell'applicazione potrebbero essere influenzate.
Test, Test ... Metti quanta più logica possibile nel modello e sarai in grado di testarlo correttamente. I test unitari testano i dati e il modo in cui sono formati testando il modello, mentre i test funzionali testano il modo in cui vengono instradati o controllati testando i controller, quindi ne consegue che non è possibile testare l'integrità dei dati a meno che non siano in il modello.
j