Ruby on Rails #18: Active Record - LPC-Ltda/Ruby-on-Rails GitHub Wiki

Los modelos son archivos ruby almacenados en el directorio app/models.

  • Cada base de datos se compone de Tablas
  • Cada tabla se compone de registros
  • Cada registro se compone de campos

ActiveRecord opera con el modelo ORM (mapeo de objetos relacionales)

1.- Una tabla de la base de datos corresponde a una clase modelo que hereda de ActiveRecord

class Usuario < ActiveRecord::Base attr_accessible :nombre, :apellidos end

Si en nuestra base de datos existe una tabla llamada Usuarios, debe existir un modelo llamado usuario y por convención RoR sabrá que están vinculados. La tabla ha de estar en plural y el modelo en singular.

UsuarioAnonimo - usuario_anonimos Amigo - amigos Perfil - perfiles

2.- Un registro es un objeto

class HomeController < ApplicationController def index @usuario = Usuario.find(1) end end

3.- Un campo es una propiedad de un objeto. Los nombres de los campos deben estar en minuscula y singular, se pueden usar underscores.

Una convención importante es el uso de la clave primaria y foránea. Cuando creemos una tabla desde la línea de comandos no tendremos que especificar ninguna clave primaria ya que crea automáticamente el campo id que se tomará como tal, donde se almacena un número autoincrementado. La indicación en una tabla de que existe una clave foránea se indicará de la siguiente manera

nombre_tabla_foránea_id => categoria_id

Configuración de base de datos

Por defecto al crear una aplicación por defecto se usa Sqlite3. Si deseamos cambiar ActiveRecord cuenta con un método llamado establish_connection donde le especificaremos la configuración de conexión con la base de datos.

Desde el terminal podemos generar nuestra aplicación con la correspondiente configuración por defecto, de las siguiente bases de datos:

  • Mysql
  • Oracle
  • PostgreSql
  • Sqlite
  • Fronbase
  • Ibm_db
  • Jdbcmysql
  • SQL Server
  • Jbdcsqlite3
  • Jdbcpostgresql
  • Jdbc

Rails new (nombre_aplicación) -d (tipo_base_de_datos)

Conectar con Postgresql

Primero debemos instalar la gema para operar con postgreSQL.

[Gemfile] gem 'pg'

[Terminal] bundle install

[Terminal] rails new curso_rails -d postgresql

[database.yml] development: adapter: postgresql encoding: unicode database: curso_development pool: 5 username: curso_rails password:

test: adapter: postgresql encoding: unicode database: curso_test pool: 5 username: curso_rails password:

production: adapter: postgresql encoding: unicode database: curso_production pool: 5 username: curso_rails password:

Nuestro primer Modelo

Crear las bases de datos con los diferentes nombres dependiendo del ambiente de trabajo, es lo único que ActiveRecord no podrá hacer por nosotros.

Existe un generador en Rails para la creación de los modelos:

rails generate model [tabla][campos]

  • tabla - indicaremos el nombre del modelo en singular, y creará una tabla dentro de la misma base de datos en plural
  • campos - Especificaremos los campos de nuestra tabla

Tipos soportados :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean, :references

[Terminal] rails g model Usuario nombre:string apellidos:string edad:integer

Al llamar a la clase ActiveRecord crea un paso intermedio antes de crear definitivamente la tabla, que es lo que se conoce como migración, y que veremos más adelante. Crea un modelo dentro de el directorio app/models llamado usuario.rb con los archivos necesarios para los test automatizados, test_unit

Modelo generado

[app/models/usuario.rb] class Usuario < ActiveRecord attr_accessible :apellidos, :edad, :nombre end

Los atributos apellidos, edad y nombres son los campos. Por defecto vienen con permiso para realizar asignaciones masivas mediante la creación de un nuevo registro. Esto puede ser en ocasiones peligroso.

[Terminal] usuario = Usuario.new(:nombre=>"Paco", :apellidos=>"Moles", :edad=>32) #=>usuario.edad #=>32

Si suprimimos el campo edad del método attr_accessible, tendremos que asignar asignaciones específicas al atributo.

[Terminal] usuario = Usuario.new(:nombre=>"Paco", :apellidos=>"Moles", :edad=>32) #=>usuario.edad #=> nil

Este intento de asignación devolverá el error ActiveModel::MassAssignmentSecurity::Error:Can't mass-assign protected

[Terminal] usuario = Usuario.new

usuario.edad = 32 #=> 32

Visualizar nuestra tabla

Se debe ejecutar la migración

[Terminal] rake db:migrate

Con esto hemos convertido de modelo a tabla.

Resumen de Convenciones

1.- Los modelos tienen el nombre en singular de nuestra tabla. Esto puede ser anulado indicando en nuestro modelo el nombre de la tabla con la que se relaciona el modelo.

class Usuario < ActiveRecord::Base self.table_name = "nombre_tabla" end

2.- Asigna por defecto un campo id que será la clave primaria para la tabla. Esto puede ser también anulado.

class Usuario < ActiveRecord::Base self.primary_key = "clave_primaria" end

3.- Si queremos indicar que una tabla contiene un campo que es una clave foránea se debe indicar de la siguiente forma.

NombreModelo_id usuario_id # Clave foránea dentro de una tabla.

Novedades de Rails 4.0.0

Cambia el nombre del error por intento de asignación masiva

[Rails 3.2] ActiveModel::MassAssignmentSecurity::Error

[Rails 4.0] ActiveModel::ForbiddenAttributesError

Parametros fuertes

En rails 4.0 se pasa la responsabilidad de la protección las asignaciones masivas a los controladores con los métodos permit, para señalar los campos permitidos y require donde especificaremos el modelo que es permitido.

[Rails 4.0] class Usuario < ActiveRecord end

class UsuariosController < ApplicationController def crear @usuario = Usuario.new params.require(:usuario).permit(:nombre, :apellidos) @usuario.save end end

O lo podemos encapsular en un método

[Rails 4.0] class Usuario < ActiveRecord::Base end

class UsuariosController < ApplicationController def crear @usuario = Usuario.new datos_usuario @usuario.save end

def datos_usuario params.require(:usuario).permit(:nombre, :apellidos) end end

Para activarlo debemos añadir una línea en config/application.rb

[Rails 4.0] config.active_record.whitelist_attributes = false

La ventaja del uso de la gema strong parámeters, es que liberamos de esa carga a los modelos, y el control pasa a ser responsabilidad de los controladores. Para probar:

Usuario.create :nombre=>"Luis", :apellidos=>"Ochoa"