#16 Virtual Attributes
Sotto è riportata una form di registrazione che accetta un nome, un cognome e una password.
Questi campi sono presenti anche nella nostra struttura di database:
create_table "users", :force => true do |t| t.string "first_name" t.string "last_name" t.string "password" end
Ma che succederebbe se volessimo cambiare l’interfaccia in modo tale da avere un campo full_name
al posto dei due campi first_name
e last_name
? Lo possiamo fare usando un attributo virtuale. Per prima cosa, cambieremo la nostra vista e combineremo i campi dei due nomi.
<h1>Register</h1> <% form_for @user do |form| %> <ol class="formList"> <li> <%= form.label :full_name, 'Full Name' %> <%= form.text_field :full_name %> </li> <li> <%= form.label :password, 'Password' %> <%= form.password_field :password %> </li> </ol> <% end %>
new.html.erb
con il campo full_name
.
Ora, facendo il submit della form, Rails cercherebbe l’attributo full_name
nel modello User
, che attualmente non esiste. Possiamo crearlo definendo un attributo virtuale per la proprietà full_name
.
class User < ActiveRecord::Base # Getter def full_name [first_name, last_name].join(' ') end # Setter def full_name=(name) split = name.split(' ', 2) self.first_name = split.first self.last_name = split.last end end
I metodi getter e setter definiti sul modello User
.
Il metodo getter prende i valori di first_name
e last_name
per l’istanza corrente di utente e li restituisce, unendoli con uno spazio. Il metodo setter divide il valore passato la primo spazio incontrato e imposta i valori delle property first_name
e last_name
come la prima e la seconda parte della stringa così spezzata.
Usare attributi virtuali significa che l’interfaccia utente può non necessariamente proporre all’utente solo campi direttamente mappati sul database. Questo è particolarmente utile quando si usa Rails per collegarsi ad un database legacy e non si possono modificare i campi in quelle tabelle.
Vediamolo in azione
Proviamo ora la nostra nuova form e vediamo come funziona. Inseriremo “John Smith” come nome completo e “secret” come password.
Processing UsersController#create (for 127.0.0.1 at 2009-01-10 21:55:44) [POST] Parameters: {"user"=>{"password"=>"secret", "full_name"=>" John Smith"}, "commit"=>"Add user", "authenticity_token"=>"6990f4ad21cb4f9c812a6f10ceef51faa4f46ce7"} User Create (0.4ms) INSERT INTO "users" ("first_name", "last_name", "password") VALUES('John', 'Smith', 'secret')
Estratto del log di sviluppo che mostra il nuovo utente mentre viene inserito nel database.
Possiamo notare del log di sopra che alla action create
viene mandato il full_name (e di conseguenza anche al modello User
), ma al database vengono passati i valori separati first e last name mediante la INSERT
.
Gli attributi virtuali forniscono un modo potente e flessibile per permettere di personalizzare le interfacce utente.