【问题标题】:Rails dynamic foreign key for has_many relationship用于has_many关系的Rails动态外键
【发布时间】:2023-03-21 03:29:01
【问题描述】:

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

我想做这样的事情。

has_many :requests, :foreign_key => mentor? ? 'mentor_id' : 'student_id', :class_name => 'Request'

我有导师吗?模型中的方法,但它给了我一个 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)

有没有办法在不为学生和导师制作单独模型的情况下解决这个问题?我觉得看到他们都使用相同的字段是不必要的。

【问题讨论】:

  • 为什么要不同的 id 列?这个逻辑应该只在用户模型上,而不是在请求上。你想要的也是不可能的......:D

标签: ruby-on-rails ruby activerecord model


【解决方案1】:

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

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

如何以正确的方式实现这一点?

你有一个用户模型,学生导师都是用户,所以他们都会继承此模型。

class User < ActiveRecord::Base
end

class Student < User
end

class Mentor < User
end

这意味着什么?好吧,这意味着 User 模型拥有(无需您做任何其他事情)一个字段 type 将包含“Student”或“Mentor”或不包含任何内容,具体取决于您初始化对象的方式:

user = User.create()
student = Student.create()
mentor = Mentor.create()

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

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

现在你可以写了:

student.requests
mentor.requests
request.owner

【讨论】:

  • 请求属于导师和学生。我该怎么做呢? Rails 如何知道它是学生还是导师?
  • 我刚刚搜索了单表继承,非常感谢您的帮助! :)
【解决方案2】:

我不太确定您需要什么。 相同的模型结构,一个用户可以成为多个学生的导师?一个学生可以有一个导师?是吗?

如果是,那么自加入呢?

class User < ActiveRecord::Base
  has_many :students, :class_name => "User", :foreign_key => "mentor_id"
  belongs_to :mentor, :class_name => "User"
end

这样你就可以调用student.mentor和mentor.students

【讨论】:

  • 我在另一个模型中有学生-导师关系,因为导师可以有多个学生。
  • 但是按照我发布的方式,您也可以让多个学生与一位导师关联 =)
  • 抱歉打扰了!斯巴达已经回答了,我在标签搜索中没有看到。
猜你喜欢
  • 2012-12-19
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 1970-01-01
相关资源
最近更新 更多