Ruby este una dintre cele mai populare limbi folosite pe web. Am început o nouă sesiune aici pe Nettuts +, care vă va prezenta Ruby, precum și marile cadre și instrumente care merg împreună cu dezvoltarea Ruby. Astăzi, vom analiza pietrele de date DataMapper pentru a începe să funcționeze cu o bază de date în Ruby.
DataMapper este un ORM: o mapare obiect-relațională. Practic, este o bibliotecă care vă permite să lucrați cu baza de date din codul orientat pe obiecte. Nu există absolut niciun SQL în acest tutorial deloc. Cu toate acestea, un ORM utilizează o bază de date obișnuită sub capace; vom folosi sqlite3 astăzi, dar ați putea folosi un adaptor diferit pentru a lucra cu o bază de date mysql, postgresql sau altă bază de date.
În cântând cu Sinatra - App Recall, Dan Harper te-a prezentat la DataMapper. În acest tutorial, vom face o scufundare mai profundă în lucrul cu biblioteca.
Primul pas este instalarea pietrelor necesare. Funcționalitatea DataMapper este împărțită în mai multe pietre diferite, deci va trebui să instalați mai multe părți diferite. Desigur, nu vom lucra cu toate acestea; dar acestea sunt pietrele pe care trebuie să le instalați.
dm-Postgres-adaptor
, dm-mysql-adaptor
, sau orice ți se potrivește cu fantezia ta.Odată ce ați instalat toate aceste pietre (vedeți ultimul capitol dacă trebuie să știți cum să instalați pietre prețioase), suntem gata să mergem.
Să începem prin crearea unui model de bază. Modelele sunt definite în clase. Cu toate acestea, trebuie mai întâi să ne conectăm la baza noastră de date.
De fapt, primul lucru este să cerem bibliotecile noastre să se afle în fruntea dosarului nostru.
necesită 'dm-core' impune 'dm-timestamps' necesită 'validări dm' necesită 'migrare dm'
Deci, acum că avem DataMapper în mediul înconjurător, să ne conectăm la baza de date.
DataMapper.setup: implicit, "sqlite: // # Dir.pwd /database.db"
Primul parametru indică aplicației DataMapper să utilizeze adaptorul implicit pentru tipul de bază de date. Al doilea este linkul / adresa URL a bazei de date. Din moment ce folosim sqlite, doar conectăm la un fișier de bază de date. Rețineți că nu trebuie să creați acest fișier; DataMapper o va crea pentru noi.
Acum suntem gata să creăm modelul. După cum știți, aceasta este o clasă.
clasa User include DataMapper :: Resource property: id, Proprietatea Serial: username, String proprietate: email, String end
Primul pas este includerea DataMapper :: Resource
modul. Acest lucru vă oferă metodele personalizate pe care le veți folosi în clasă. Cea mai importantă metodă aici este proprietate
. Aici, îl folosim pentru a crea trei proprietăți diferite: un id, un nume de utilizator și un e-mail. După cum vedeți, primul parametru din proprietate
este un simbol care este numele proprietății. Al doilea este tipul. Înțelegi String, desigur, dar ce e serial. De fapt, proprietate: id, serial
este prescurtarea DataMapper pentru cheia primară; 'serial' este un număr întreg de auto-incrementare. Aceasta este cheia dvs. primară!
Acum că am creat modelul nostru, trebuie să migrăm baza de date. Dacă nu sunteți familiarizat cu migrarea unei baze de date, este procesul de modificare a schemei bazei de date. Aceasta ar putea fi adăugarea unei coloane, redenumirea unei coloane sau schimbarea proprietăților unei coloane. DataMapper oferă două moduri de a face acest lucru:
DataMapper.auto_migrate! DataMapper.auto_upgrade!
Diferența este aici auto_migrate!
va șterge toate datele din baza de date; auto_upgrade!
metodele încearcă să concilieze ceea ce există deja în baza de date cu modificările pe care doriți să le faceți. Modul în care funcționează acest lucru este că, după clasa de model, veți apela una dintre aceste metode. Nu vrei să fugi auto_migrate!
de fiecare dată când încărcați modelul, desigur, dar poate doriți să rulați auto_upgrade!
la fiecare reîncărcare în dezvoltare. Am făcut-o așa în Sinatra:
configurați: dezvoltare DataMapper.auto_upgrade! Sfârșit
Veți observa că până acum nu am fost nevoiți să atingem o singură interogare SQL; acesta este punctul de utilizare pe ORM este că puteți scrie codul normal și să lucreze cu baze de date relaționale.
Acum, când avem picioarele ude cu DataMapper, să luăm modelul nostru la un alt nivel. Să începem cu marcajele de timp.
Îi cerem dm-timestamp-
gem, deci de ce să nu-l folosiți? Dacă adăugăm proprietăți "create_at" și "updated_at" la model, această gem va actualiza automat acele câmpuri.
proprietate: created_at, proprietatea DateTime: updated_at, DateTime
Desigur, nu trebuie să adăugați ambele, dacă nu le doriți.
Există mai multe opțiuni pe care le puteți adăuga în fiecare câmp. De exemplu, dacă doriți ca un câmp să fie necesar sau unic sau să aveți o valoare implicită, puteți face acest lucru acolo. Să creați un model post pentru a prezenta câteva dintre acestea:
clasa Post include DataMapper :: Resource property: slug, String, key: true, unic_index: true, default: lambda resource, prop | resource.title.downcase.gsub "", "-" proprietate: titlu, String, cerut: true property: body, Text, required: true property: created_at, DateTime property: updated_at, DateTime end
Lucrăm puțin aici; titlul și corpul nostru sunt câmpuri obligatorii. Definim proprietatea "slug" ca cheie primară și spunem că trebuie să fie un indice unic. Nu vă speriați de valoarea implicită a cuvântului "slug". Desigur, puteți folosi doar o valoare brută de orice tip de proprietate, dar facem ceva mai mult. Ruby (și alte limbi) are lambda, pe care le-ați putea gândi ca o mică funcție. E ceva ce poate lua parametrii? și returnează o valoare, la fel ca o funcție. Dacă folosim o valoare lambda ca valoare a proprietății "implicite", DataMapper îi va transmite resursa (sau baza de date cu care lucrați) și proprietatea însăși (în acest caz, "slug"). Deci, aici, ceea ce facem este să luăm valoarea resource.title
(proprietatea titlului), punerea în litere mici și utilizarea gsub
metoda (cred global Substitution) pentru a comuta fiecare spațiu într-o linie. În felul acesta:
"Acesta este un titlu"
Va deveni acest lucru:
„Acest lucru este-o--titlu“
Notă: Nu vă confundați cu modul în care folosim opțiunile aici. Mai întâi de toate, amintiți-vă că atunci când un hash este ultimul parametru al unei metode, nu este necesar să adăugăm bretelele curl. De asemenea, cu Ruby 1.9, există o sintaxă hash nouă. Anterior, hash-urile au arătat astfel:
: cheie => "valoare"
Puteți face acest lucru în 1.9, și trebuie să utilizați dacă nu utilizați simbolurile ca chei. Dar, dacă utilizați simboluri ca chei, puteți face acest lucru în schimb:
valoare cheie"
Practic, trebuie doar să mutați colonul până la sfârșitul simbolului (fără spațiu!) Și să eliminați racheta.
Există multe lucruri pe care le puteți face cu validarea în DataMapper și puteți citi totul aici. Cu toate acestea, să aruncăm o privire la elementele de bază.
Există două modalități de a face validări; vom folosi metoda care adaugă validările dvs. la hash-ul opțiunilor. Pentru proprietatea de e-mail din modelul de utilizator, vom seta validarea formatului:
proprietate: e-mail, String, format:: email_address
În acest caz, folosim un regex încorporat pe care îl oferă DataMapper; am putea pune o regex personalizat acolo dacă vrem altceva.
Să solicităm o anumită lungime pentru parolă:
proprietate: parola, String, lungime: 10? 255
Dacă nu sunteți familiarizat cu 10? 255 notație, este o gamă Ruby. Spunem că parola trebuie să aibă o lungime între 10 și 255 de caractere.
Ce zici de cheile străine? DataMapper face acest lucru real ușor. Să asociem modelele de utilizator și postare. Vrem ca un utilizator să poată avea multe postări și un post care să aparțină unui utilizator.
În modelul Utilizator, adăugați această linie
are n,: posturi
Apoi, în modelul Post, procedați astfel:
belong_to: utilizator
În baza de date, aceasta adaugă a numele de utilizator
proprietate la o masă postală. În practică, este foarte ușor; o să vedem asta în curând.
Dacă doriți să personalizați intrarea pentru o anumită proprietate, puteți adăuga accesoriile proprietății personalizate. De exemplu, să presupunem că dorim să ne asigurăm că numele de utilizator al unui utilizator este întotdeauna stocat în litere mici. Putem adăuga metode de accesare a proprietăților similare cu cele ale unei clase obișnuite. În acest fel, luăm valoarea pe care utilizatorul încearcă să o stocheze și să o repare. Să o facem:
def username = new_username super new_username.downcase sfârșit
Definim definiția Nume de utilizator =
, atunci când numele de utilizator este atribuit, acesta va fi inferior. super
parte doar trece valoarea noastră la metoda super metoda a acestei metode, care este cea pe care o suprasolicităm.
Notă: Conform documentației (a se vedea aici și aici), ar trebui să putem face @username = new_username.downcase
în metoda de mai sus. Asta am făcut în scenariu și, după cum știți, nu a funcționat așa cum era de așteptat. De când am înregistrat scenariul, am descoperit că documentația este greșită, și asta super
este calea de a face acest lucru.
Ei bine, acum că modelele noastre sunt create, să adăugăm câteva înregistrări pentru a le testa. Putem face acest lucru în câteva moduri. În primul rând, putem crea o înregistrare cu nou
metoda, trecerea unui hash de atribute sau atribuirea individuală a acestora.
user = User.new nume utilizator: "JoeSchmo", nume: "Joe", nume: "Schmo", email: "[email protected]", parola: "password_12345" user.save user = User.new user.username = "Andrew" # etc user.save
Atunci când se utilizează Utilizator nou #
, trebuie să apelați Salvați
metoda de a pune efectiv înregistrarea în baza de date. Dacă există o eroare (amintiți aceste validări?), Salvați
metoda va reveni false. Apoi, puteți merge la erori
de proprietate pentru a vedea erorile; este un obiect DataMapper :: Validations :: ValidationsErrors, dar puteți repeta erorile cu fiecare
metodă.
user.errors.each do | error pune sfârșitul erorii
Dacă doriți să faceți și să salvați o înregistrare într-o singură lovitură, utilizați crea
metodă, desigur trecându-i un hash de atribute.
User.create nume de utilizator: "joeschmo", nume: "Joe", nume: "Schmo", email: "[email protected]", parola: "password _! @ # $%
Boom: creat și salvat!
Ce zici de găsirea unei înregistrări în baza de date? Dacă știți cheia înregistrării pe care o căutați, trebuie doar să utilizați metoda de obținere:
User.get (1) Post.get ("this-is-a-title")
Da, vedeți că aceasta funcționează atât cu chei întregi normale cât și cu alte tipuri de chei. Din moment ce am spus că bolta a fost cheia în Post
model, putem obține
de către slug.
Ce zici de acele domenii care ar putea fi aceleași pentru mai multe înregistrări? Aveți trei opțiuni pentru aceasta: în primul rând, ultima și toate. Dă-i doar un hash și ei primesc înregistrările pentru tine
User.first firstname: "Andrew" User.last (: nume => "Schmo") User.all #gets toate mesajele
Mai puteți face mult cu DataMapper; verificați documentația pentru mai mult! Apăsați caseta de întrebări dacă aveți întrebări.