#16 Virtual Attributes
Debajo vemos un formulario de alta de usuario que acepta un nombre (first_name), un apellido (last_name)y una clave (password).
Estos campos también se encuentran en la estructura de nuestra base de datos:
create_table "users", :force => true do |t| t.string "first_name" t.string "last_name" t.string "password" end
Pero y si queremos cambiar la interfaz de usuario para que tengamos un campo full_name
(nombre completo), en vez de un campo nombre y otro apellido. Esto lo podemos conseguir utilizando un atributo virtual. Primero, vamos a cambiar nuestro código de la vista y combinaremos ambos campos.
<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 el campo full_name
.
Ahora, podemos enviar el formulario y buscará un atributo full_name
en el modelo User
(Usuario), que actualmente no posee. Podemos crearlo definiendo un atributo virtual para 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
Los métodos getter y setter definidos en el modelo User
.
El método getter, obtiene los valores del nombre y del apellido para el usuario y los devuelven unidos por un espacio. El método setter, separa en el primer espacio el valor pasado y coloca el nombre y el apellido para que sean las partes primera y segunda de la cadena separada.
El uso de propiedades virtuales, conlleva a que la interfaz de usuario no deba tener un campo para mapear cada campo en la tabla correspondiente de la base datos. Esto es especialmente útil cuando se usa Rails para conectar una base de datos legacy y no puede alterar los campos en sus tablas.
En acción
Vamos a probar nuestro nuevo formulario. Vamos a ingresar “John Smith” como full name (nombre completo) y “secret” como clave.
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')
Una parte del log de desarrollo mostrando el nuevo usuario siendo agregado a la base de datos.
Podemos ver del log de desarrollo de arriba que el full_name fue enviado a la acción create (y luego al modelo User), pero que el primer nombre y el apellido separados, fueron pasados a la instrucción INSERT que se le paso a la base de datos.
Los atributos virtuales nos dan una forma poderosa y flexible de personalizar nuestras interfaces de usuario.