1

我正在尝试建立一个自我参照关系,如这段精彩的视频中所述 - http://railscasts.com/episodes/163-self-referential-association - 它主要是有效的,但并不完全有效。

我有这些实体: 用户,可以是导师或被指导者;匹配项,有一个mentor_id(user.id)、mentee_id(user.id)和status_id;和状态,这是一个简单的查找表。

我的用户模型如下所示:

class User < ActiveRecord::Base   

has_many :matches
has_many :mentors, :through => :matches
has_many :mentees, :through => :matches
has_many :statuses, :through => :matches

end

我的状态模型如下所示:

class Status < ActiveRecord::Base
  has_many :matches
end

我的 Match 模型如下所示:

class Match < ActiveRecord::Base
  belongs_to :mentor, :class_name => "User"
  belongs_to :mentee, :class_name => "User"
  belongs_to :status 
end

当我放置 user.mentors时,我得到SQLite3::SQLException: no such column: matches.user_id: SELECT "users".* FROM "users" INNER JOIN "matches" ON "users".id = "matches".mentor_id WHERE ( (“匹配”.user_id = 1))

简单地说,我希望做user.matches.find(1).status.id .. 关于我做错了什么的任何想法?

提前致谢。乔恩

4

3 回答 3

4

我很确定您正在寻找:

class User < ActiveRecord::Base
  has_many :match_mentors, :foreign_key => "mentee_id", :class_name => "Match"
  has_many :match_mentees, :foreign_key => "mentor_id", :class_name => "Match"

  has_many :mentors, :through => :match_mentors
  has_many :mentees, :through => :match_mentees

  def status_with_mentee mentee_id
    match = match_mentees.find_by_mentee_id(mentee_id)
    return nil if match.nil? 
    match.status
  end
end


class Match < ActiveRecord::Base
  belongs_to :mentor, :class_name => "User"
  belongs_to :mentee, :class_name => "User"
  belongs_to :status

  after_create :set_status

  def set_status
   Status.find(1).matches << self #replace 1 with the id you want
  end
end

这使:

u = User.create
u.mentors               => [] 
u.mentors.create        => #<User id: 2, name: nil, created_at: "2011-06-17 19:02:17", updated_at: "2011-06-17 19:02:17"> 
u.mentors               => [#<User id: 2, name: nil, created_at: "2011-06-17 19:02:17", updated_at: "2011-06-17 19:02:17">] 
v = u.mentors.first     => #<User id: 2, name: nil, created_at: "2011-06-17 19:02:17", updated_at: "2011-06-17 19:02:17"> 
v.mentees               => [#<User id: 1, name: nil, created_at: "2011-06-17 18:58:44", updated_at: "2011-06-17 18:58:44">] 

编辑,关联学员:

current_user.mentees << User.find(params[:mentee_id])

Rails 将正确处理所有事情。

要知道导师和他的一位学员之间的关系是什么:

current_user.status_with_mentee(params[:mentee_id])

当然,您可以为导师关系创建相同的

于 2011-06-17T19:06:07.517 回答
1

为了使用user.mentors你需要一个

belongs_to :user 

在您的 Match 模型中,以便它知道它与哪个用户相关联。

(您的匹配表还需要一个 user_id)

于 2011-06-17T14:55:18.720 回答
0

问题是User模型不知道Match要获取哪些记录。在你的User模型中,你告诉它 it has_many :matches,所以它假设user_id你的表中有一个列matches。但是在你的matches表中,你只有mentor_idand mentee_id

你需要告诉我们你想要做什么。您是否要获取用户出现的所有匹配项,无论它是作为导师还是被指导者?或者,如果他是导师,他是否只“拥有”一场比赛?还是师徒?

可能的解决方案

如果您想要的是User.first.matches返回用户出现的所有匹配项,无论是作为学员还是导师,这是一个可能的解决方案。

class User < ActiveRecord::Base
  def matches
    Match.where("mentor_id = :id OR mentee_id = :id", { :id => self.id })
  end

  def mentors
    User.joins("INNER JOIN matches ON matches.mentor_id = users.id").where("matches.mentee_id = ?", self.id)
  end

  def mentees
    User.joins("INNER JOIN matches ON matches.mentee_id = users.id").where("matches.mentor_id = ?", self.id)
  end
end

保持其他模型不变。这将使您能够做User.first.matches,User.first.matches.find(1).status.idUser.first.mentors.first.mentees

如果有人知道如何保持关联并仍然检索用户作为导师和被指导者出现的匹配项,我现在也想这样做。

于 2011-06-17T15:35:14.957 回答