In questa serie per principianti, guardiamo ad AntiPattern, che - come suggerisce il nome - rappresentano praticamente l'opposto dei modelli di design. Sono scoperte di soluzioni a problemi che dovresti assolutamente evitare.
In questo articolo ci concentreremo sul principale View AntiPattern-PHPitis e lavoreremo attraverso un paio di tecniche per mantenere i tuoi punti di vista magri e cattivi. Avere tonnellate di codice Ruby nelle visualizzazioni non è solo sgradevole, ma spesso non necessario.
Rails viene fornito con ERb (Embedded Ruby), fuori dalla scatola, e penso che per ora non sia necessario lanciare motori di rendering di visualizzazione come Slim per i nostri esempi. Se pensate che "convenzione sulla configurazione" si applica principalmente ai livelli del modello e del controller, state perdendo molte delle cose che rendono il lavoro con Rails così veloce e progressivo. Prendersi cura del livello di visualizzazione include non solo il modo in cui si compongono il markup, ma anche CSS / Sass, JavaScript, visualizza gli helper e i modelli di layout. Visto da quell'angolo, diventa un po 'più profondo di quanto si possa pensare all'inizio. L'enorme numero di tecnologie che possono essere coinvolte nella creazione dei tuoi punti di vista suggerisce che bisogna fare attenzione a mantenere le cose in ordine, chiare e flessibili.
Dal momento che il modo in cui scriviamo markup e stili è molto meno vincolato rispetto alla modellazione di domini, vuoi essere più cauto nel mantenere le cose il più semplici possibile. La manutenzione dovrebbe essere la priorità numero uno. Poiché le riprogettazioni o le iterazioni di progettazione possono essere più frequenti di ampie modifiche al livello del modello, la preparazione per il cambiamento assume un significato completamente nuovo quando si tratta del livello dell'utente. Il mio consiglio: non costruire necessariamente per il futuro, ma anche, con ogni mezzo, non sottovalutare il tasso di cambiamento, specialmente se si dispone di uno di quei "ragazzi idea" che conoscono le implementazioni del team. Quello che mi piace dell'approccio di Rails nei confronti delle visualizzazioni in MVC è che viene trattato come ugualmente importante e che le lezioni apprese dal dominio del modello sono state incorporate nella vista, ogni volta che è possibile e utile. Altri quadri sembrano essere d'accordo, dal momento che hanno integrato molte di queste idee introdotte da Rails.
Poiché l'ultimo articolo era un po 'più ampio, ho scelto questo argomento come un piccolo attimo di respiro. I seguenti articoli sui controller e sui test di Rails sono di nuovo più grandi. Gli AntiPatterns per le viste non sono così tanti, ma sono ugualmente importanti. Ci concentreremo su quello principale, PHPitis, e lavoreremo con un paio di tecniche per mantenere le tue opinioni magre e meschine. Dal momento che la vista è il tuo livello di presentazione, forse dovresti stare particolarmente attento a non creare un pasticcio pericoloso. Andiamo ad esso!
Perché abbiamo MVC in primo luogo? Sì, perché la separazione delle preoccupazioni sembrava la cosa più ragionevole da fare. Certo, le implementazioni di questa idea variano un po 'qua e là, ma il concetto generale di avere responsabilità distinte per ogni livello è la motivazione principale per costruire applicazioni robuste. Avere tonnellate di codice nel proprio livello di visualizzazione potrebbe non essere estraneo agli sviluppatori che provengono dal lato PHP delle cose, anche se i loro framework sono già stati raggiunti (pesantemente influenzati da cose come Rails?) - ma in Ruby-land queste cose hanno a lungo stato un AntiPattern ad alta voce.
I problemi evidenti, come il mescolare responsabilità e duplicazioni a parte, si sentono semplicemente cattivi e pigri, anche un po 'stupidi, per essere sinceri. Certo, capisco, quando sviluppi molto all'interno di un framework, linguaggio o qualsiasi ecosistema, è facile diventare complice o insensibile verso cose del genere. Quello che mi piace delle persone che spingono Ruby è che queste cose sembrano avere molto meno peso - questo potrebbe essere un motivo per cui l'innovazione non è mai sembrata un problema all'interno della comunità. Qualunque cosa funzioni meglio vince l'argomento, e possiamo andare avanti.
Quindi questa è un'intera sezione dedicata a bashing PHP? Affatto! In passato, le app di PHP avevano la reputazione di avere deboli separazioni tra modelli, visualizzazioni e controller (forse questo era uno dei motivi principali per cui le persone sentivano che scrivere app con Rails era molto più allettante). Avere singoli file con il codice per tutti e tre i livelli non sembrava così sexy. Quindi quando inseriamo tonnellate di codice Ruby o di dominio nelle nostre visualizzazioni, inizia ad assomigliare al terribile stile PHP di strutturare le cose: PHPitis. Solo alcune cose sono così negative quando si tratta di sviluppare applicazioni web, credo. Quando ti preoccupi degli sviluppatori felici e della tua sanità mentale futura, non riesco a capire perché qualcuno dovrebbe seguire questa strada: c'è solo dolore in futuro, sembra.
Rails offre un sacco di chicche per minimizzare il più possibile il codice nella vista. Devi imparare i modi di aiutanti, layout e preprocessori per ottenere una visione più chiara. Una semplice regola empirica è quella di mantenere la logica di dominio fuori dai tuoi punti di vista, senza scorciatoie!
Il prezzo da pagare per essere pigri su questo è difficile da sopravvalutare. Il codice Ruby che deve essere nel livello di presentazione dovrebbe essere il più piccolo e il più semplice possibile, nonché organizzato in modo intelligente. La tua ricompensa sarà un codice che è una gioia da estendere e da mantenere, e i nuovi membri del team avranno anche un tempo più facile che avvolgeranno la loro mente attorno alla nuova base di codice. Come bonus, anche i designer curiosi che codificano non si arrabbieranno e nasconderanno il cibo marcio nell'insalata se manterrai tonnellate di codice Ruby dal loro markup.
Conoscere la miriade di metodi di supporto in Rails migliorerà in modo significativo la qualità del livello di presentazione. Non solo pulirà le cose e inietterà l'aumento di velocità occasionale in produttività, ma soprattutto ti aiuterà a combattere PHPitis.
La cosa che dovresti apprezzare di questi helper è che rappresentano estrazioni dal codice comunemente necessario. Invece di reinventare la ruota, in caso di dubbio, controlla se non c'è già un aiutante in giro che risolva il problema nella vista, lo stesso vale per i modelli e i controller, ovviamente.
Ecco un elenco di helper che dovresti esaminare subito:
form_for
fields_for
Collegamento a
content_for
Diamo un'occhiata a form_for
primo. So che le forme sono un po 'noiose e non così sexy per un argomento, ma ti incoraggio fortemente a leggerle per familiarizzare con i dettagli più fini. È importante capire come funzionano. Ricordo spesso di guardarli senza dare loro molta attenzione. Certo, puoi farli lavorare abbastanza facilmente senza capire cosa sta succedendo sotto il cofano. In futuro, potrei prendere il tempo di scrivere un articolo completo su di loro. Nel frattempo, ti consiglio vivamente di dedicare un po 'di tempo a controllare la documentazione, almeno apprezzerai quanto sia conveniente Rails a occuparsi di materiale formale.
L'esempio seguente mostra l'HTML di un piccolo modulo di cui abbiamo bisogno per creare agenti. Accetta solo tre parametri come input: nome
, numero
e licence_to_kill
. Un sacco di codice per questo piccolo compito, in realtà. Il authenticity_token
proviene da Rails: è una cosa di sicurezza che protegge l'app da "falsificazione di richieste cross-site".
Scrivere un modulo a mano non è solo lungo, ma anche incline all'errore. Inoltre, se ci apprestassimo in questo modo, dovremmo anche risolvere il problema con i vari percorsi e le classi CSS che potremmo aver bisogno per creare un nuovo oggetto e aggiornare un effetto one-in esistente, avremmo bisogno di duplicare i moduli per creare e modificare i record. Come vedrai presto, Rails ti incontra più di metà. Verdetto: comunque tu lo metti, l'approccio manuale è sgradevole e privo di comodità.
Potremmo scendere lungo la strada seguente, che non fa un uso perfetto delle convenzioni in Rails. Controlla, non farlo. In pratica mostra che non stai gestendo gli strumenti disponibili a tuo vantaggio e stai duplicando il modulo per nuovo
e modificare
Azioni.
<%= form_for :agent, url: agents_path(@agent), html: method: :post do |form_object| %> <%= form_object.label :name %> <%= form_object.text_field :name %> <%= form_object.label :number %> <%= form_object.text_field :number %> <%= form_object.label :licence_to_kill %> <%= form_object.check_box :licence_to_kill %> <%= form_object.submit 'Create New Agent' %> <% end %>
Quello che succede qui è che il form builder porta il modello che ti serve per il modulo.
<%= form_object.text_field :name %>
Dietro le quinte, la riga sopra viene espansa in quanto segue:
<%= text_field :agent, :name %>
Il form_for
il metodo richiede un paio di argomenti:
url
hashhtml
hashnamespace
hashL'url dell'URL serve a specificare le opzioni di routing. Ciò significa che è possibile specificare manualmente a quale percorso di instradamento si inviano i percorsi con nome e forma utile. Questo stile è chiamato "modo generico" perché è necessario configurare manualmente il file form_for
chiamata.
Perché questa soluzione non è ottimale? Perché vogliamo mantenere la logica aziendale fuori dalle nostre viste e controllori il più possibile. Un effetto collaterale di questo è che abbiamo bisogno di cambiare un minor numero di parti quando necessario.
Nel caso lo avessi perso, questo approccio non ci ha fornito ID e classi per il modulo
tag automaticamente. Quelli per ingresso
i tag, tuttavia, sono stati generati per te. Lo risolveremo in un minuto. Basta sapere cosa si può ottenere gratuitamente e che probabilmente dovresti usarlo a tuo vantaggio. Se hai bisogno di qualcosa di diverso o di uno spazio dei nomi aggiuntivo, puoi usare il html
hash o il namespace
hash per specificare le cose un po 'di più.
<%= form_for :agent, url: agents_path(@agent), html: method: :post, class: 'create_agent', id: 'unique_agent', namespace: 'mi6' do |form_object| %>
Non male! Ora il modulo
il tag ha la classe e l'id specificati, qualunque cosa faccia fluire il tuo sangue, e il ingresso
i tag sono nominati con MI6
. Quasi lì.
Questo è chiamato "stile orientato alle risorse" e ha la minima quantità di Ruby che è necessario scrivere nelle viste. Con questo approccio, vogliamo fare affidamento sull'identificazione automatica delle risorse. Rails individua i percorsi di cui ha bisogno in base all'oggetto stesso. Non solo, ti dà un output HTML diverso per creare un nuovo oggetto o per modificarne uno esistente. Dietro le quinte, Rails chiede all'oggetto se esiste già e agisce di conseguenza.
La creazione di moduli in questo modo è un uso intelligente delle convenzioni ed aiuta ad evitare la duplicazione. Una linea e tutto il sollevamento pesante è fatto per te.
<%= form_for @agent do |form_object| %> <%= form_object.label :name %> <%= form_object.text_field :name %> <%= form_object.label :number %> <%= form_object.text_field :number %> <%= form_object.label :licence_to_kill %> <%= form_object.check_box :licence_to_kill %> <%= form_object.submit %> <% end %>
Molto meglio, non è vero? Ora otteniamo esattamente ciò di cui abbiamo bisogno sia per gli oggetti esistenti che per quelli nuovi. Inoltre, non è stato necessario aggiungere testo al pulsante di invio. Rails si è preso cura di questo e si adatta anche a oggetti nuovi o esistenti.