Pergunta

Eu tenho os três modelos a seguir: usuário, projeto e atribuição.

Um usuário has_many Projetos através de uma tarefa. No entanto, a tarefa realmente tem dois Chaves estrangeiras relacionadas a um usuário: user_id (representando o usuário que foi atribuído ao projeto) e completer_id (representando o usuário que concluiu o projeto).

Muitas vezes, user_id e completer_id será o mesmo (se o usuário que recebeu o projeto o concluir). No entanto, se outro usuário o concluir, user_id e Completer_id serão diferentes.

No meu modelo de usuário, tenho o seguinte:

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

Eu gostaria de fazer outra associação, chamada :completed_projects, que usa completer_id como a chave estrangeira para o usuário no :through modelo, em vez de :user_id. É possível fazer isso?

E, como um aparte, estou ciente do :foreign_key opção. No entanto, esta opção é ignorada ao usar :through, então eu gostaria de saber se há uma maneira de fazer isso sem ele.

Por fim, devo mencionar que estou aberto a outros designs, se não puder ser feito dessa maneira e alguém pode pensar em uma maneira melhor.

Foi útil?

Solução

Você sempre pode usar o SQL para a seleção se o ActiveRecord não puder expressar facilmente o relacionamento fora da caixa:

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

Outras dicas

Você tem outros meta -dados em sua tabela de atribuições?

Caso contrário, eu usaria o HABTM e adicionaria o Completer_id à tabela de projetos, faz sentido morar lá de qualquer maneira.

Se você precisar/quiser usar Has_Many: através, você pode olhar usando o nome do nome (versão do Rails da Rails) para que você possa dizer user.projects.completed e user.projects.incomplete

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top