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.save
2.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.save
Un 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.destroy
2.4 Eliminazione
user = User.find_by(name: 'David')
user.destroy
3 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.messages
2.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
end
2.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
end
2.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) }
end
2.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" }
end
Se 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" }
end
2.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 }
end
2.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 }
end
2.9 presence
Controlla che gli attributi indicati non siano vuoti.
class Person < ActiveRecord::Base
validates :name, :login, :email, presence: true
end
Nel 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
end
Nel 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
end
2.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
end
3 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
end
Posso anche usare una stringa a cui sarΓ fatto lβeval
.
class Person < ActiveRecord::Base
validates :surname, presence: true, if: "name.nil?"
end
3.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
end
4. 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
end
Blocco
class User < ActiveRecord::Base
validates :login, :email, presence: true
before_create do
self.name = login.capitalize if name.blank?
end
end
Di seguite sono elencate tutte le possibili callback disponbili:
Creazione
before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
after_commit/after_rollback
Aggiornamento
before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save
after_commit/after_rollback
Eliminazione
before_destroy
around_destroy
after_destroy
after_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
.