1. Convenzioni
- Tabelle: nome plurale con gli underscore che separano le parole
- Model: sinfolari con la prima lettera di ogni parola in maiuscolo
- Chiavi esterne:
singularized_table_name_id(esempiitem_id,order_id)
| Model / Class | Table / Schema |
|---|---|
| Article | articles |
| LineItem | line_items |
| Deer | deers |
| Mouse | mice |
| Person | people |
2. CRUD
2.1 Creazione
Gli oggetti ActiveRecord possono essere creati da un hash (metodo create) oppure posso istanziarli e settare i loro attributi successivamente. Le seguenti istruzioni sono analoghe
2.1.1 New
user = User.new
user.name = "David"
user.occupation = "Code Artist"
user.save2.1.2 Create
user = User.create(name: "David", occupation: "Code Artist")2.2 Lettura
users = User.all
user = User.first
david = User.find_by(name: 'David')
users = User.where(name: 'David', occupation: 'Code Artist').order(created_at: :desc)2.3 Aggiornamento
Una volta che ho trovato un oggetto, posso aggiornarne gli attributi per poi salvarlo su DB.
user = User.find_by(name: 'David')
user.name = 'Dave'
user.saveUn modo veloce per eseguire tale operazione Γ¨ il seguente (esegue giΓ il save)
user = User.find_by(name: 'David')
user.update(name: 'Dave')Per aggiornare tutti i record Γ¨ possibile utilizzare la seguente istruzione
user = User.find_by(name: 'David')
user.destroy2.4 Eliminazione
user = User.find_by(name: 'David')
user.destroy3 Controlli
Con ActivRecord Γ¨ possibile eseguire dei controlli sui dati prima che questi vengano scritti sul database (quindi non vengono lanciate con il metodo new ma con il metodo create (oppure dopo un quasiasi metodo save))
1. Errori
Per verificare che un particolare oggetto abbia o meno superato le validazioni posso usare la funzione errors[:attribute] che fornisce un array per tutti gli errori di tale attributo. Deve essere lanciato dopo che le validazioni sono partite
class Person < ActiveRecord::Base
validates :name, presence: true
end
>> p = Person.new
>> p.errors.messages
>> p.errors.messages2.Validazioni
2.1 acceptance
Valida se un checkbox Γ¨ stato selezionato quando un form Γ¨ stato submittato. PuΓ² essere lanciato anche su un attributo che non esiste direttamente nel DB, in tal caso verrΓ creato un attributo virtuale. PuΓ² essere utilizzato principalmente se lβutente deve accettare i terms of service, confermare la lettura di un qualche testo io simili.
class Person < ActiveRecord::Base
validates :terms_of_service, acceptance: true
end2.2 validates_associated
Da utilizzare quando il model ha delle associazioni con altri model che devono essere validate. Quando viene lanciato il save il metodo valid? viene chiamato su tutti gli oggetti associati.
class Library < ActiveRecord::Base
has_many :books
validates_associated :books
end2.3 confirmation
Da usare quando ho due campi di testo e voglio che entrambi contengano lo stesso valore. Questa validazione crea un attributo virtuale il cui nome Γ¨ il nome del campo che deve essere conrfermato con un _confirmation alla fine. Per esempio, se voglio confermare la mail, opero di conseguenza:
class Person < ActiveRecord::Base
validates :email, confirmation: true
validates :email_confirmation, presence: true
end
<%= text_field :person, :email %>
<%= text_field :person, :email_confirmation %>2.4 Exclusion
Controlla che lβattributo non sia contenuto in un determinato insieme
class Account < ActiveRecord::Base
validates :subdomain, exclusion: { in: %w(www us ca jp) }
end2.5 format
Controlla che lβattributo faccia il match con una espressione regolare
class Product < ActiveRecord::Base
validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
message: "only allows letters" }
endSe sostituisco il :with con il :without chiedo che non esegua il match con la regexp.
2.6 inclusion
Controlla che gli attributi siano inclusi in un determinato insieme
class Coffee < ActiveRecord::Base
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} is not a valid size" }
end2.7 length
class Person < ActiveRecord::Base
validates :name, length: { minimum: 2 }
validates :bio, length: { maximum: 500 }
validates :password, length: { in: 6..20 }
validates :registration_number, length: { is: 6 }
end2.8 numericality
Controlla che lβattributo in questione abbia solo numeri (integer o float). Se voglio solo interi devo aggiungere lβopzione :only_integer a true.
class Player < ActiveRecord::Base
validates :points, numericality: true
validates :games_played, numericality: { only_integer: true }
end2.9 presence
Controlla che gli attributi indicati non siano vuoti.
class Person < ActiveRecord::Base
validates :name, :login, :email, presence: true
endNel caso in cui voglia verificare la presenza di una associazione devo eseguire il seguente codice:
class LineItem < ActiveRecord::Base
belongs_to :order
validates :order, presence: true
end
class Order < ActiveRecord::Base
has_many :line_items, inverse_of: :order
endNel caso in cui voglia validare la presenza di un campo booleano devo eseguire il seguente trucco (in quando false.blank? fornisce true)
validates :boolean_field_name, presence: true
validates :boolean_field_name, inclusion: { in: [true, false] }
validates :boolean_field_name, exclusion: { in: [nil] }2.10 abscence
Verifica che gli attributi indicati siano vuoti
class Person < ActiveRecord::Base
validates :name, :login, :email, absence: true
end2.11 uniqueness
Controlla che lβattributo indicato sia lβunico presente su database. Deve essere associato ad un vincolo di unicitΓ anche su DB.
class Account < ActiveRecord::Base
validates :email, uniqueness: true
end3 Validazioni condizionali
Talvolta conviene validare un attributo solo se una determinata condizione Γ¨ soddisfatta.
class Order < ActiveRecord::Base
validates :card_number, presence: true, if: :paid_with_card?
def paid_with_card?
payment_type == "card"
end
endPosso anche usare una stringa a cui sarΓ fatto lβeval.
class Person < ActiveRecord::Base
validates :surname, presence: true, if: "name.nil?"
end3.1 Raggruppare istruzioni condizionali
class User < ActiveRecord::Base
with_options if: :is_admin? do |admin|
admin.validates :password, length: { minimum: 10 }
admin.validates :email, presence: true
end
end4. Visualizzare gli errori nelle view
Non esistono degli helper prefatti, tendenzialmente si puΓ² eseguire una strittura del genere
<% if @article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>4. Callback
Posso associare del codice che deve essere lanciato ad un determinato momento nella vita di un oggetto.
4.1 Implementazione
Posso definire la callback con due modalitΓ , o come metodo o come blocco.
Metodo
class User < ActiveRecord::Base
validates :login, :email, presence: true
before_validation :ensure_login_has_a_value
protected
def ensure_login_has_a_value
if login.nil?
self.login = email unless email.blank?
end
end
endBlocco
class User < ActiveRecord::Base
validates :login, :email, presence: true
before_create do
self.name = login.capitalize if name.blank?
end
endDi seguite sono elencate tutte le possibili callback disponbili:
Creazione
before_validationafter_validationbefore_savearound_savebefore_createaround_createafter_createafter_saveafter_commit/after_rollback
Aggiornamento
before_validationafter_validationbefore_savearound_savebefore_updatearound_updateafter_updateafter_saveafter_commit/after_rollback
Eliminazione
before_destroyaround_destroyafter_destroyafter_commit/after_rollback
5. Migrazioni
Le migrazioni sono utilizzate per gestire lo schema effettivo del DB e i suoi cambiamenti. Le migrazioni sono memorizzate in file e eseguite mediante il comando rake.