Rails动态外键为has_many关系

Anu*_*jan 1 ruby activerecord model ruby-on-rails

我有一个用户模型,用于保存所有用户.我的应用程序,导师和学生中的用户有两种类型,但它们具有相同的结构.

我想做这样的事情.

has_many :requests, :foreign_key => mentor? ? 'mentor_id' : 'student_id', :class_name => 'Request'
Run Code Online (Sandbox Code Playgroud)

我有导师?模型中的方法,但它给我一个method_missing错误.我假设它是因为它正在寻找方法dynamic_matchers.rb

这是它给出的错误

/var/lib/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/dynamic_matchers.rb:55:in 'method_missing': undefined method 'mentor?' for #<Class:0x00000001b40630> (NoMethodError)

如果没有为学生和导师制作单独的模型,有没有办法解决这个问题?我觉得没必要看到他们都使用相同的字段.

Rai*_*dal 5

好吧,让我纠正一下:这是不可能的,即使在乌托邦世界中,或者你找到了解决方法,这肯定是不正确的.

你实际上在寻找的是继承(STI或Rails中的单表继承)和多态之间的混合.

你怎么能以正确的方式实现这个?

您有一个用户模型,学生导师都是用户,因此他们将继承此模型.

class User < ActiveRecord::Base
end

class Student < User
end

class Mentor < User
end
Run Code Online (Sandbox Code Playgroud)

这意味着什么?嗯,这意味着用户模型保持(没有你做任何其他事情)一个字段类型,它将包含'学生'或'导师',或者根据你初始化对象的方式没有任何内容:

user = User.create()
student = Student.create()
mentor = Mentor.create()
Run Code Online (Sandbox Code Playgroud)

现在,你的请求可以属于一个学生或一个导师.所以在这里你可以像这样设置一个多态关联:

class Student < User
  has_many :requests, as: :owner
end

class Mentor < User
  has_many :requests, as: :owner
end

class Request < ActiveRecord::Base
  belongs_to :owner, polymorphic: true
end
Run Code Online (Sandbox Code Playgroud)

现在你可以写:

student.requests
mentor.requests
request.owner
Run Code Online (Sandbox Code Playgroud)