ActiveRecord vine cu un set puternic de validatori și alte caracteristici pentru atributele unui model de date persistente. Pe de altă parte, formele sunt una dintre cele mai vechi și mai importante blocuri ale aplicațiilor web de astăzi - o interfață esențială pentru introducerea de către utilizatori. Dintre cei doi ajutoare formate pe care le oferă Rails, "form_for" presupune, de asemenea, că lucrați cu un fel de obiect persistent. Astfel, poate beneficia pe deplin de toate caracteristicile înregistrate active, adică de validări.
Acest lucru este minunat pentru obiectele persistente cu reprezentări susținute de bază de date. Dar ce se întâmplă atunci când aveți nevoie de o formă complexă care nu reflectă o înregistrare persistentă de un fel?
În acest tutorial voi vorbi despre soluțiile posibile pentru această problemă și cum să implementați unul în Rails 4 (Models Active).
În acest tutorial, vom construi o aplicație cu un formular în care un utilizator poate adăuga un feedback care este apoi salvat într-o bază de date. Această aplicație va avea, de asemenea, valori și vizualizări, exact așa cum le creați pentru un model bazat pe baze de date, dar apoi vom trece prin câteva dintre modificările din model pentru al face fără tabel. Și toate caracteristicile trebuie să funcționeze așa cum sunt, fără a face alte schimbări. Nu există actualizări, ștergeți sau găsiți acțiuni pentru feedback.
Pentru acest tutorial, presupun că aveți o subestimare de bază a cadrului Rails și puteți crea sau genera cu ușurință controloare de bază, modele și vederi. Presupun că știți și un pic despre cum funcționează rutele și validările. În momentul în care am scris acest tutorial, am folosit Rails 4.2.5 și SQLite 3.8.10.2.
Există multe situații când aveți o clasă pe care doriți să o utilizați ca un model tipic ActiveRecord, dar nu doriți să persistenți datele în baza de date. De exemplu, este posibil să aveți un formular de contact sau ceva mai complex ca o plângere sau un formular de feedback.
În aceste situații, pentru a rezolva această problemă, o abordare ar fi folosirea form_tag metoda helper, care vă oferă câmpuri de formular personalizate care fac ceea ce aveți nevoie fără să le obligați vreun model.
Acest lucru funcționează bine, dar form_tag pot deveni repede obosiți să scrieți și să vă mențineți dacă manipulați mai mult de câțiva câmpuri din cauza necesității de a gestiona numirea numeroaselor atribute și validări ale acestora pe cont propriu. În curând, controlerul dvs. va ajunge să se ocupe de o mulțime de logică și de tone de paramuri de formă, care probabil nu este o soluție ideală.
O abordare mai curată și mai flexibilă ar fi dacă am putea să folosim cumva același lucru form_for cu un model și toate validările și alte avantaje pe care le vin, dar fără a fi nevoie să aibă reprezentări bazate pe bază de date ale atributelor sale.
Rails oferă exact acest tip de soluție: Modelul activ-care este la fel ca un model normal, dar fără mese. Oferă exact aceeași modalitate ușoară de validare și aproape toate celelalte bunuri expediate cu ActiveRecord. Vă ajută să păstrați coerența structurii aplicației, deoarece utilizați modele pentru a reprezenta obiecte în aplicația dvs. oricum, rutele sunt disponibile gratuit, iar formarea clădirilor este la fel de ușoară ca înainte cu form_for.
În acest pas vom genera o aplicație inactivă pentru a juca în timpul acestui tutorial.
Porniți terminalul și tastați aceste comenzi pentru a crea o nouă aplicație:
# Creați o bază Rails App rails noi tableless cd tableless # Creați un controler cu numai noi, creați și succes Acțiuni șine genera feedback-ul controlerului noi creare de succes - skip-rute # Crearea unui model de șine generează numele modelului de feedback: șir e-mail: : mesaj șir: sugestie de text: text
Așa ești tu Structura directorului va arata.
Aici vă voi oferi fragmentele de cod pentru toate fișierele pe care trebuie să le completați. Codul este destul de explicativ. Puteți descărca această aplicație din repozitoriul GitHub conectat la acest post sau urmați pașii mei pentru a crea una de unul singur.
→ / Config /routes.rb
resurse: feedbacks,: only => [: new,: create] obțineți feedback / success = = 'feedbacks success', ca:: success
→ /app/views/feedbacks/success.html.erb
<%= notice %>
<%= link_to 'Submit New Feedback', new_feedback_path %>
→ / app / opinii / feedback-uri /new.html.erb
Feedback nou
<%= form_for(@feedback) do |f| %> <% if @feedback.errors.any? %><% end %><%= pluralize(@feedback.errors.count, "error") %> a interzis ca acest feedback să fie salvat:
<% @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
clasa 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 /modele / feedbacks.rb
feedback de clasă < 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
Pentru ao implementa pe serverul local, mai întâi trebuie să executați următoarele comenzi pentru a crea baza de date în sistemul dumneavoastră.
cd fără tabel / rake db: migrați
Dacă ați urmat tutorialul în acest moment, comanda de mai sus ar trebui să creeze în mod implicit o bază de date sqlite3. Pentru ao schimba, puteți să accesați database.yml-de dragul acestui tutorial, voi merge cu sqlite3.
Acum fugi rails s
în terminalul dvs. și ar trebui să vedeți ceva similar cu acesta.
Și cu asta ar trebui să rulați cu succes o aplicație falsă.
Acum este momentul să testați ceea ce am creat. Apăsați acest traseu în browser pentru a verifica dacă totul funcționează bine: http: // localhost: 3000 / feedback-uri / noi
Ar trebui să vedeți un formular ca mai sus. Acum, apăsați butonul Trimiteți fără a completa niciun câmp pentru a verifica dacă validările funcționează bine.
Grozav. Ar trebui să vedeți șase erori de validare, ca mai sus. Acum putem încerca să completați valorile corecte și să trimiteți formularul.
Ar trebui să vedeți ceva similar pe ecran. Să verificăm baza de date pentru înregistrarea pe care tocmai am introdus-o.
Deschide-ți Terminal, accesați directorul de proiect și tastați comenzile de mai jos.
șine db
pentru a porni clientul bazei de date din consola dvs..SQLite> .tables
pentru a lista toate tabelele din baza de date (DB este selectat implicit).SQLite> .headers pe
pentru a afișa Nume de coloane în rezultatele dvs..SQLite> selectați * din feedback-uri;
pentru a vedea toate feedback-urile din baza de date.Și aici putem vedea că feedback-ul a fost salvat cu succes în baza de date. Dacă te uiți în jurnale, poți găsi și INTRODUCE întrebare.
Și cu asta testul nostru sa terminat. Acum, că totul pare să funcționeze bine, hai să trecem la soluție.
A implementa Modelul activ, primul lucru pe care trebuie să îl faceți este să eliminați moștenirea modelului de feedback < ActiveRecord::Base
deoarece nu vrem ca acest model să mai aibă o back-end de baze de date.
De îndată ce vom face acest lucru, formularul nostru nu va mai funcționa, deoarece validatorii sunt furnizați de ActiveRecord. Dar adăugând includeți modelul ActiveModel :: Model
pe următoarea linie trebuie să restaurați totul.
Modelul dvs. ar trebui să arate așa.
feedback-ul claselor include ActiveModel :: Model
Al doilea lucru este să adăugați attr_accessor
pentru a genera getters și setters pentru toate atributele, cum ar fi acest lucru.
attr_accessor: nume,: email,: adresa,: mesaj,: sugestie
Acum rezultatul final al modelului ar trebui să arate așa.
feedback-ul de clasă include ActiveModel :: Model attr_accessor: nume,: email,: adresa,: mesaj,: sugestie # validare câmpuri pentru baza de date. validează: nume, prezență: true validează: e-mail, prezență: adevărat, lungime: în: 5 ... 255 validează:
Fixarea modelului nu este suficientă pentru ca aplicația noastră să se comporte așa cum vrem. Controlorul se așteaptă încă să salveze obiectul de date recepționat în baza de date din crea metodă. @ feedback.save
nu va funcționa deoarece nu avem o bază de date înapoi pentru a salva noul feedback.
Putem rezolva această problemă prin schimbare @ feedback.save
în @ feedback.valid?
deoarece efectuăm acum doar validările din modelele noastre și, pe baza acestui eveniment de succes, puteți efectua orice sarcină preferată în cadrul acestui bloc de cod, adică să trimiteți notificări, să trimiteți e-mail sau evenimente log, etc.
clasa 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
Să reluăm testele pe care le-am efectuat mai devreme.
Apăsați pe traseu http: // localhost: 3000 / feedback-uri / noi
și să prezinteformularul fără completarea câmpurilor. Toate validările ar trebui să funcționeze ca mai devreme.
Grozav. Acum putem încerca să trimitem formularul cu valori valide.
Și iată-te - același mesaj de succes.
Acum, ultimul lucru pe care trebuie să-l verificăm este baza de date.
Pentru asta, deschide-ți Terminal, accesați directorul de proiect și tastați comenzile de mai jos.
șine db
pentru a porni clientul bazei de date din consola dvs..SQLite> .tables
pentru a lista toate tabelele din baza de date (DB este selectat implicit).SQLite> .headers pe
pentru a afișa Nume de coloane în rezultatele dvs..SQLite> selectați * din feedback-uri
pentru a vedea toate feedback-urile din baza de date.Și de data aceasta, deoarece modelul nostru nu este susținut cu nici o tabelă de baze de date, nu veți găsi valorile nou prezentate în tabel.
Dacă verificați jurnalele de consolă, de asemenea, nu vedem INTRODUCE interogare mai mult.
Deci, cu asta am terminat cu ActiveModel
, și am văzut cât de ușor este să creați un model fără masă. ActiveModel este în îmbunătățiri grele, astfel încât să vă puteți aștepta la unele modificări în versiunile viitoare ale Rails.
Am folosit doar validările și atribuirile de atribute din acest tutorial pentru a păstra lucrurile simple și clare. Dar aruncați o privire în directorul care conține codul pentru ActiveModel pe GitHub.
Putem vedea din listă că ActiveModel include, printre altele, clase pentru metode de atribut, serializare, callbacks și urmărire murdară. În acest fel puteți să țineți cont de funcțiile viitoare și să vă familiarizați și cu ceilalți.