ActiveRecord viene fornito con un potente set di validatori e altre funzionalità per gli attributi di un modello di dati persistenti. D'altra parte, le forme sono uno dei più vecchi e più importanti elementi costitutivi delle attuali applicazioni Web: un'interfaccia essenziale per l'input dell'utente. Dei due helper di form che Rails fornisce, "form_for" presuppone anche che tu stia lavorando con qualche tipo di oggetto persistente. Quindi può trarre il massimo vantaggio da tutte le funzionalità di registrazione attive, ovvero convalide.
Questo è tutto ottimo per oggetti persistenti con rappresentazioni supportate da database. Ma cosa succede quando hai bisogno di una forma complessa che non rifletta un record persistente di qualche tipo?
In questo tutorial parlerò delle possibili soluzioni per questo problema e di come implementarne uno in Rails 4 (Modelli attivi).
In questo tutorial, creeremo un'applicazione con un modulo in cui un utente può aggiungere un feedback che viene poi salvato in un database. Questa applicazione avrà anche convalide e viste, esattamente come le crei per un modello supportato da database, ma poi passeremo attraverso alcune delle modifiche nel modello per renderlo senza tablature. E tutte le funzionalità devono funzionare come sono, senza apportare ulteriori modifiche. Non ci sono azioni di aggiornamento, cancellazione o ricerca per il feedback.
Per questo tutorial, presumo che tu abbia una comprensione di base del framework Rails e possa facilmente creare o generare controller, modelli e viste di base. Presumo che tu sappia anche un po 'su come funzionano le rotte e le convalide. Al momento di scrivere questo tutorial, stavo usando Rails 4.2.5 e SQLite 3.8.10.2.
Ci possono essere molte situazioni quando si ha una classe che si desidera funzionare come un tipico modello di ActiveRecord, ma non si desidera mantenere i dati nel database. Ad esempio, potresti avere un modulo di contatto o qualcosa di più complesso come un modulo di reclamo o feedback.
In quelle situazioni, per risolvere questo problema un approccio sarebbe usare il form_tag metodo di supporto, che ti fornisce campi modulo personalizzati che fanno ciò di cui hai bisogno senza doverli associare a nessun modello.
Funziona bene, ma form_tag può diventare rapidamente noioso scrivere e mantenere se gestiscono più di pochi campi a causa della necessità di gestire nominare i numerosi attributi e le loro convalide da soli. Presto il tuo controller finirà per gestire un sacco di logica e tonnellate di param di modulo, che probabilmente non è la soluzione ideale.
Un approccio più pulito e più flessibile sarebbe se potessimo in qualche modo usare lo stesso form_for con un modello e tutte le validazioni e altri vantaggi offerti, ma senza la necessità di avere rappresentazioni dei suoi attributi supportate da database.
Rails offre esattamente questo tipo di soluzione: il Modello attivo-che è proprio come un modello normale ma senza i tavoli. Fornisce esattamente lo stesso semplice metodo di convalida e quasi tutti gli altri gadget forniti con ActiveRecord. Ti aiuta a mantenere coerente la struttura dell'applicazione, perché stai utilizzando i modelli per rappresentare oggetti nella tua app in ogni caso, i percorsi sono disponibili gratuitamente e la creazione di moduli è facile come prima form_for.
In questo passaggio genereremo un'applicazione fittizia con cui giocare durante questo tutorial.
Avvia il tuo terminale e digita questi comandi per creare una nuova applicazione:
# Crea un Rails app di base rails nuovo tableless senza tableless # Crea un controller con solo nuovi, crea e successo I binari di azione generano feedback del controller nuovo crea successo --skip-routes # Crea un modello Rails genera il nome di feedback del modello: string email: string address : string message: text suggerimento: text
Questo è il tuo Struttura della directory guarderà.
Qui fornirò i frammenti di codice per tutti i file che devi compilare. Il codice è piuttosto auto-esplicativo. Puoi scaricare questa app dal repository GitHub collegato a questo post o seguire i miei passi per crearne una da solo.
→ / Config /routes.rb
risorse: feedback,: only => [: new,: create] ottieni 'feedbacks / success' => 'feedbacks # success', come:: successo
→ /app/views/feedbacks/success.html.erb
<%= notice %>
<%= link_to 'Submit New Feedback', new_feedback_path %>
→ / app / views / valutazione /new.html.erb
Nuovo feedback
<%= form_for(@feedback) do |f| %> <% if @feedback.errors.any? %><% end %><%= pluralize(@feedback.errors.count, "error") %> vietato questo feedback di essere salvato:
<% @feedback.errors.full_messages.each do |message| %>
- <%= message %>
<% end %><%= f.label :name %>
<%= f.text_field :name %><%= f.label :email %>
<%= f.text_field :email %><%= f.label :address %>
<%= f.text_field :address %><%= f.label :message %>
<%= f.text_area :message %><%= f.label :suggestion %>
<%= f.text_area :suggestion %><%= f.submit %><% end %> <%= link_to 'Back', feedbacks_path %>
→ /app/controllers/feedbacks_controller.rb
class FeedbacksController < ApplicationController def new @feedback = Feedback.new end def create @feedback = Feedback.new(feedback_params) respond_to do |format| if @feedback.save format.html redirect_to success_path, notice: 'Feedback was successfully submitted.' else format.html render :new end end end def success end private def feedback_params params.require(:feedback).permit(:name, :email, :address, :message, :suggestion) end end
→ / app /modelli / feedbacks.rb
feedback di classe < ActiveRecord::Base # fields validation for the database. validates :name, presence: true validates :email, presence: true, length: in:5… 255 validates :address, presence: true validates :message, presence: true validates :suggestion, presence: true end
Per distribuirlo sul tuo server locale, devi prima eseguire i seguenti comandi per creare il database nel tuo sistema.
cd tableless / rake db: migrate
Se hai seguito il tutorial fin qui, il comando sopra dovrebbe creare un database sqlite3 per impostazione predefinita. Per cambiarlo, puoi saltare a database.yml-per il bene di questo tutorial, andrò con sqlite3.
Ora corri rotaie s
nel tuo terminale e dovresti vedere qualcosa di simile a questo.
E con questo dovresti eseguire con successo un'applicazione fittizia.
Ora è il momento di testare ciò che abbiamo appena creato. Colpisci questa rotta nel tuo browser per verificare se tutto funziona bene: http: // localhost: 3000 / valutazione / new
Dovresti vedere una forma come sopra. Ora premi il pulsante di invio senza compilare alcun campo per verificare se le convalide funzionano correttamente.
Grande. Dovresti vedere sei errori di convalida, come sopra. Ora possiamo provare a compilare i valori corretti e inviare il modulo.
Dovresti vedere qualcosa di simile sul tuo schermo. Controlliamo il database per il record che abbiamo appena inserito.
Apri il tuo terminale, vai alla directory del tuo progetto e digita i comandi seguenti.
rotaie db
per avviare il client del database nella tua console.SQLite> .tables
per elencare tutte le tabelle nel database (il database è selezionato per impostazione predefinita).SQLite> .headers on
per visualizzare il Nomi di colonne nei tuoi risultati.SQLite> seleziona * dai feedback;
per vedere tutti i feedback nel database.E qui possiamo vedere il feedback è stato salvato con successo nel database. Se si esaminano i registri, è anche possibile trovare il file INSERIRE domanda.
E con questo i nostri test sono finiti. Ora che tutto sembra funzionare bene, passiamo alla soluzione.
Implementare Modello attivo, la prima cosa che devi fare è rimuovere l'ereditarietà del modello di feedback < ActiveRecord::Base
poiché non vogliamo che questo modello abbia più un back-end del database.
Non appena lo facciamo, il nostro modulo non funzionerà più, poiché i validatori sono forniti da ActiveRecord. Ma aggiungendo include ActiveModel :: Model
sulla riga successiva dovrebbe ripristinare tutto.
Il tuo modello dovrebbe apparire così ora.
Il feedback della classe include ActiveModel :: Model
La seconda cosa è aggiungere attr_accessor
per generare getter e setter per tutti gli attributi, come questo.
attr_accessor: nome,: email,: indirizzo,: messaggio,: suggerimento
Ora il risultato finale del modello dovrebbe assomigliare a questo.
class Feedback includono ActiveModel :: Model attr_accessor: nome,: email,: indirizzo,: messaggio,: suggerimento # campi di convalida per il database. convalida: nome, presenza: true convalida: email, presenza: true, lunghezza: in: 5 ... 255 convalida: indirizzo, presenza: true convalida: messaggio, presenza: true convalida: suggerimento, presenza: vero fine
La correzione del modello non è sufficiente per far funzionare la nostra app come vogliamo. Il controllore si aspetta comunque di salvare l'oggetto dati ricevuto nel database nel creare metodo. @ feedback.save
non funzionerà perché non abbiamo un database back-end per salvare più il nuovo feedback.
Possiamo risolvere questo problema cambiando @ feedback.save
in @ feedback.valid?
dal momento che stiamo solo eseguendo le convalide nei nostri modelli ora e in base a questo evento di successo, puoi eseguire qualsiasi operazione preferita all'interno di questo blocco di codice, ad esempio inviare notifiche, inviare e-mail o eventi di registro, ecc..
class FeedbacksController < ApplicationController def create @feedback = Feedback.new(feedback_params) respond_to do |format| if @feedback.valid? # Something interesting can be done here # - send notifications # - send email # - log events format.html redirect_to success_path, notice: 'Feedback was successfully submitted.' else format.html render :new end end end
Riprendiamo i test che abbiamo eseguito in precedenza.
Hit the route http: // localhost: 3000 / valutazione / new
e inviareil modulo senza compilare alcun campo. Tutte le convalide dovrebbero funzionare come prima.
Grande. Ora possiamo provare inviando il modulo con valori validi.
E qui vai - lo stesso messaggio di successo.
Ora l'ultima cosa che dobbiamo controllare è il database.
Per questo, apri il tuo terminale, vai alla directory del tuo progetto e digita i comandi seguenti.
rotaie db
per avviare il client del database nella tua console.SQLite> .tables
per elencare tutte le tabelle nel database (il database è selezionato per impostazione predefinita).SQLite> .headers on
per visualizzare il Nomi di colonne nei tuoi risultati.SQLite> seleziona * dai feedback
per vedere tutti i feedback nel database.E questa volta, dal momento che il nostro modello non è supportato da alcuna tabella di database, non troverai i nuovi valori inviati nella tabella.
Se controlli i log della tua console, anche noi non vediamo il INSERIRE interrogare più.
Quindi con questo abbiamo finito con ActiveModel
, e abbiamo visto quanto sia facile creare un modello senza tabella. ActiveModel ha notevoli miglioramenti, quindi puoi aspettarti alcuni cambiamenti nelle versioni di Rails.
Abbiamo appena usato le convalide e le assegnazioni degli attributi in questo tutorial per mantenere le cose semplici e chiare. Ma dai un'occhiata alla directory che contiene il codice per ActiveModel su GitHub.
Possiamo vedere dall'elenco che ActiveModel include anche classi per metodi di attributo, serializzazione, callback e tracciamento sporco, tra le altre cose. In questo modo puoi tenere d'occhio le funzionalità imminenti e acquisire familiarità con gli altri.