ruby-on-rails - llaves - relaciones en ruby on rails
Especificar la clave externa en una relaciĆ³n has_many: through (2)
Tengo los siguientes tres modelos: Usuario, Proyecto y Asignación.
Un usuario tiene has_many
proyectos a través de una tarea. Sin embargo, la asignación en realidad tiene dos claves externas que se relacionan con un usuario: user_id
(que representa al usuario al que se le asignó el proyecto) y completer_id
(que representa al usuario que completó el proyecto).
A menudo, user_id
y completer_id
serán los mismos (si el usuario que se le asignó el proyecto lo completa). Sin embargo, si otro usuario lo completa, user_id y completer_id serán diferentes.
En mi modelo de Usuario, tengo lo siguiente:
class User < ActiveRecord::Base
has_many :assignments
has_many :incomplete_assignments, :class_name => ''Assignment'',
:conditions => ''completer_id IS NULL''
has_many :completed_assignments, :class_name => ''Assignment'',
:foreign_key => ''completer_id''
# this is the important one
has_many :incomplete_projects,
:through => :assignments,
:source => :project,
:conditions => ''completer_id IS NULL''
end
Me gustaría hacer otra asociación, llamada :completed_projects
, que utiliza completer_id
como la clave foránea para el usuario en el :through
modelo, en lugar de :user_id
. ¿Es posible hacer esto?
Y, como un aparte, estoy al tanto de la opción :foreign_key
. Sin embargo, esta opción se ignora cuando se utiliza :through
, :through
lo que me gustaría saber si hay una manera de hacerlo sin ella.
Finalmente, debo mencionar que estoy abierto a otros diseños, si no se puede hacer de esta manera y alguien puede pensar en una mejor manera.
¿Tiene otros metadatos en su tabla de asignaciones?
Si no, simplemente usaría habtm y agregaría el completador_id a la tabla de proyectos, de todos modos, tiene sentido vivir allí.
Si necesita / quiere usar has_many: a través de podría ver usando named_scopes (la versión de Rails lo permite) para que pueda decir user.projects.completed
y user.projects.incomplete
Siempre puede usar SQL para la selección si ActiveRecord no puede expresar fácilmente la relación desde el primer momento:
has_many :completed_projects,
:class_name => "Project",
:finder_sql => ''SELECT p.* FROM projects p '' +
''INNER JOIN assignments a ON p.id=a.project_id '' +
''INNER JOIN users u on u.id=a.completer_id '' +
''WHERE u.id=#{id}''