Active Record es la capa de modelo del framework Ruby on Rails, y las asociaciones son una de las características fundamentales de este marco de trabajo que permiten relacionar diferentes modelos de base de datos entre sí de manera sencilla y eficiente. Entre las asociaciones disponibles, una de las más comunes es has_one
, que establece una relación uno a uno entre dos modelos.
Cuando un modelo tiene una asociación has_one
con otro modelo, significa que cada instancia del primer modelo está asociada con exactamente una instancia del segundo modelo. Esto se traduce en que en la tabla de la base de datos del primer modelo, hay una columna que contiene la clave primaria del segundo modelo, estableciendo así la relación entre ellos.

Por ejemplo, considera un sistema de gestión de usuarios y perfiles. Cada usuario puede tener un único perfil asociado a él. En este caso, la tabla de usuarios tendría una columna que almacena la clave primaria del perfil asociado a ese usuario.
En términos de código en Rails, para establecer una relación has_one
, se utiliza la macro has_one
dentro de la definición del modelo. Por ejemplo:
rubyclass Usuario < ApplicationRecord
has_one :perfil
end
En este ejemplo, la clase Usuario
tiene una asociación has_one
con la clase Perfil
. Rails asume que la tabla correspondiente al modelo Perfil
contiene una columna llamada usuario_id
que almacena la clave primaria del usuario al que está asociado el perfil.
Además, Rails proporciona métodos de conveniencia para acceder a la instancia asociada. En este caso, el método sería perfil
, que devuelve la instancia del perfil asociado al usuario.
rubyusuario = Usuario.find(1)
perfil_del_usuario = usuario.perfil
Esto devolverá el perfil asociado al usuario con ID 1, si existe.
Es importante destacar que la convención de nomenclatura de Rails juega un papel crucial en la configuración de estas asociaciones. En el ejemplo anterior, Rails asume que el nombre de la tabla para el modelo Perfil
es «perfiles» y que la columna que almacena la clave primaria del usuario es «usuario_id». Sin embargo, estas convenciones se pueden anular y personalizar si es necesario, utilizando opciones adicionales en la definición de la asociación.
En resumen, has_one
es una asociación en Active Record que establece una relación uno a uno entre dos modelos, permitiendo que cada instancia de un modelo esté asociada con exactamente una instancia del otro modelo. Esto facilita la creación y manipulación de relaciones complejas en una base de datos relacional utilizando Ruby on Rails.
Más Informaciones
Claro, profundicemos un poco más en cómo funcionan las asociaciones has_one
en Active Record y cómo se pueden personalizar para adaptarse a diferentes situaciones.
En primer lugar, es importante comprender que las asociaciones has_one
están basadas en convenciones. Esto significa que Rails asume ciertas convenciones de nomenclatura en la base de datos para establecer la relación correctamente. Por ejemplo, en el caso de una asociación has_one
, Rails asume que el nombre de la columna que contiene la clave primaria del modelo asociado será el nombre del modelo en singular seguido de _id
. Esta convención se puede anular y personalizar si la estructura de la base de datos existente no sigue estas convenciones.
Para personalizar una asociación has_one
, se pueden utilizar varias opciones dentro de la definición de la asociación. Algunas de estas opciones comunes incluyen:
class_name
: Permite especificar el nombre de la clase del modelo asociado si difiere del nombre esperado según las convenciones de Rails.foreign_key
: Permite especificar el nombre de la columna en la tabla del modelo actual que contiene la clave primaria del modelo asociado, en caso de que difiera del nombre esperado por las convenciones de Rails.dependent
: Permite especificar qué sucede con el modelo asociado cuando se elimina el modelo principal. Las opciones comunes incluyen:destroy
, que elimina automáticamente el modelo asociado cuando se elimina el principal, y:nullify
, que establece la clave externa enNULL
en lugar de eliminar el modelo asociado.
Veamos un ejemplo de cómo se pueden utilizar estas opciones para personalizar una asociación has_one
:
rubyclass Usuario < ApplicationRecord
has_one :perfil,
class_name: 'PerfilUsuario',
foreign_key: 'usuario_id',
dependent: :destroy
end
En este ejemplo, la clase Usuario
tiene una asociación has_one
con la clase PerfilUsuario
, pero debido a que el nombre de la clase del modelo asociado y el nombre de la columna de la clave primaria no siguen las convenciones estándar de Rails, se especifican explícitamente utilizando las opciones class_name
y foreign_key
, respectivamente. Además, se especifica que cuando se elimina un usuario, se eliminará automáticamente su perfil asociado debido a la opción dependent: :destroy
.
Otra característica importante de las asociaciones has_one
es que se pueden establecer condiciones para restringir qué registros están asociados. Por ejemplo, si solo queremos que un usuario tenga un perfil activo, podemos agregar una condición a la asociación has_one
de la siguiente manera:
rubyclass Usuario < ApplicationRecord
has_one :perfil_activo, -> { where(estado: 'activo') }, class_name: 'PerfilUsuario'
end
En este ejemplo, la asociación has_one
se llama perfil_activo
y solo devuelve el perfil del usuario si su estado es «activo».
En resumen, las asociaciones has_one
en Active Record proporcionan una manera conveniente de establecer relaciones uno a uno entre modelos en una base de datos relacional. Aunque están basadas en convenciones, se pueden personalizar según sea necesario utilizando opciones adicionales en la definición de la asociación. Esto permite una mayor flexibilidad y adaptabilidad en el diseño de la base de datos y las relaciones entre los modelos en una aplicación Rails.