relaciones rails llaves inverse_of foreign foraneas belong ruby-on-rails model associations has-many-through

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}''