Informática → Ruby On Rails: ActiveRecord
ActiveRecord es la capa de Rails para realizar el mapeo objeto relacional (object-relational mapping ORM).
El stándar del modelo ORM dice que las tablas se mapean a clases, las filas a objetos y las columnas a atributos de los objetos.
Cuando heredamos de la clase ActiveRecord::Base estamos diciendo a la clase que mapea una tabla.
Por defecto Rails asume que el nombre de la tabla es el plural del nombre de la clase y en minúsculas, y si la clase tiene mayúsculas en la palabra, el nombre de la tabla tendrá guiones bajos (”_”).
Order => orders
TaxAgency => tax_agencies
Person => people
Si no queremos seguir estas reglas, podemos indicar el nombre de la tabla con la que trabajará la clase:
class Ship < ActiveRecord::Base
set_table_name “ship_09″
end
Sin tener que definir los atributos explícitamente, se pueden usar. Se usarán los definidos para esa tabla en la base de datos (ficheros Migration).
o = Order.find(1)
puts o.name # imprimiría el campo “name” de la tabla “orders”
o.name = “Miguel” # cambiaría el campo “name” de la tabla “orders” con el nuevo valor
Para que tuviese efecto el cambio del atributo name en la tabla habría que llamar al método “save“.
Claves primarias
Por defecto, una migración de Rails añade una columna con nombre “id” y tipo entero a tu tabla y que es la clave primaria. Pero si tú tienes un campo que será clave primaria, puedes indicarlo:
class Order < ActiveRecord::Base
self.primary_key = “number”
end
Aunque cambies el campo de la clave primaria, el campo “id” siempre indicará la clave primaria. Entonce, en nuestro caso “id” y “number” es lo mismo.
Lo aconsejable es usar un código interno para la clave primaria y no una referencia externa, ya que estas pueden cambiar.
Rails no trabaja con claves primarias compuestas, aunque existen plug-ins que lo facilitan.
Crear, Leer, Actualizar, Borrar (en inglés CRUD)
Crear
Cuando se crean objetos, se crean filas en la tabla asociada a la clase. Con el método “new” se crea el objeto, pero hasta que no se hace “save” no se guarda en la base de datos.
Existe otro método, “create” para crear el objeto y guardarlo en la base de datos directamente.
an_order = Order.create(
:name => “Pepe”
:address => “Calle ancha 1″
:payment => “card”)
Leer
Toda clase modelo tiene el método “find“. Este método puede retornar RecordNotFound si no encuentra ningún objeto, un objeto o una lista de objetos si encuentra uno o varios objetos que cumplan las condiciones de find.
Se le puede decir al método find que busque el primero (:first) o todos los objetos (:all), pasando estos símbolos como argumentos al método. En Rails 3 directamente existen los métodos “first” y “all” para hacer esto.
SQL y ActiveRecord
Para meter código SQL podemos utilizar el parámetros “:conditions“:
pos = Feature.find(:all, :conditions => “name = ‘New GUI’ and priority=’High’”)
Y si queremos meter variables en el parámetro “:conditios” debemos usar una forma que el ActiveRecord nos facilita para que no exista posibilidad de un ataque de inyección SQL, pasándole una lista, donde el primer elemento contiene el formato de la sentencia SQL indicando las posiciones donde irán las variables, y el resto de elementos las variables:
pos = Feature.find(:all, :conditions => ["name = ? and priority= ?", name, priority])
ó
pos = Feature.find(:all, :conditions => ["name = :name and priority= :priority", {:priority => priority, :name => name}])
Para el uso de “like“:
pos = Feature.find(:all, :conditions => ["name like ?", params[:name]+”%”])
Si queremos que aparezca el resultado en un orden específico debemos indicarlo con el parámetro”
rder“.
Si queremos limitar el número de filas de la consulta, lo haremos con el parámetro “:limit“.
pos = Feature.find(:all, :conditions => ["name = 'New GUI'",
rder => "priority",
:limit => 10)
Para seguir viendo resultados que han sido limitados con el parámetro ":limit" se usa el parámetro "
ffset" que indica a partir de que posición se desea el resultado.
Cuando no queremos todos los campos sino sólo algunos, utilizamos el parámetro ":select".
El parámetro ":group" añade la sentencia SQL "group by":
pos = Feature.find(:all, :select =>"sku, sum(pages) as num",
:group => "sku")
...
[artículo sin terminar]
