在has_many:through关系中指定外键

时间:2010-01-18 06:03:32

标签: ruby-on-rails model associations has-many-through

我有以下三种模式:用户,项目和作业。

用户has_many通过作业进行投射。但是,Assignment实际上有两个与用户相关的外键:user_id(代表分配了项目的用户)和completer_id(代表完成项目的用户) )。

user_idcompleter_id通常是相同的(如果分配了项目的用户完成了它)。但是,如果另一个用户完成它,则user_id和completer_id将不同。

在我的用户模型中,我有以下内容:

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

我想创建另一个名为:completed_projects的关联,它使用completer_id作为:through模型中用户的外键,而不是:user_id。有可能这样做吗?

另外,我知道:foreign_key选项。但是,使用:through时会忽略此选项,因此我想知道是否有办法在没有它的情况下执行此操作。

最后,我应该提到我对其他设计持开放态度,如果不能这样做,有人可以想到更好的方法。

2 个答案:

答案 0 :(得分:3)

如果ActiveRecord无法轻易地表达开箱即用的关系,您可以随时使用SQL进行选择:

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

答案 1 :(得分:2)

您的作业表中是否有其他元数据?

如果不是,我只会使用habtm并将completer_id添加到项目表中,无论如何都住在那里是有意义的。

如果你需要/想要使用has_many:通过你可以看看使用named_scopes(Rails版本允许),所以你可以说user.projects.completeduser.projects.incomplete