has_one/has_many 轨与主键以外的备用源 ID 关联



我有3个模型。

模型A属于模型B,模型B有许多模型C

通过使用through我可以在模型A类中设置has_many :c,through: :b

现在,每当我调用a_instance.cs它会不必要地与表 B 连接 我想要的是直接关联AC在 A 和 C 类中使用b_id

那么,当源实体和目标实体具有相同的第 3 个实体foreign_key时,如何编写没有through子句的 has_one/has_many rails 关联呢? (本例b_id(

class C
belongs_to :b #b_id column is there in DB
end
class B
has_many :cs
end
class A
belongs_to :b #b_id column is there in DB
has_many :cs , through: :b #This is the association in Question
#WHAT I WANT TO DO. So something in place of primary_key which would fetch C class directly.
has_many :cs ,class_name: 'C',foreign_key: 'b_id',primary_key: 'b_id'
end

例如,教师和学生模型属于组,教师有许多学生:

class Group < ApplicationRecord
has_many :teachers
has_many :students
end
class Teacher < ApplicationRecord
belongs_to :group
has_many :students, :foreign_key => 'group_id', :primary_key => 'group_id'
end
class Student < ApplicationRecord
belongs_to :group
end

您可以在这样的组中检索教师的学生:

teacher = Teacher.find(:teacher_id)
students = teacher.students

按照类 A、B 和 C 的示例,只更改类 A 的实现。

class A
belongs_to :b
def cs
self.id = b_id
b_cast = self.becomes(B)
b_cast.cs
end
end

安慰

A.first                    ==>#<A id: 105, b_id: 1 ...>
B.first                    ==>#<B id: 1 ...>
C.all                      ==>#<C id: 1, b_id: 1 ...>, 
#<C id: 2, b_id: 1 ...>, 
#<C id: 3, b_id: 1 ...>, 
#<C id: 4, b_id: 1 ...>

A.first.cs
A Load (0.2ms)  SELECT  "as".* FROM "as" ORDER BY "as"."id" ASC LIMIT ?  [["LIMIT", 1]]
C Load (0.1ms)  SELECT  "cs".* FROM "cs" WHERE "cs"."b_id" = ? LIMIT ?  [["b_id", 1], ["LIMIT", 11]]                 
A.first.cs                 ==>#<C id: 1, b_id: 1 ...>, 
#<C id: 2, b_id: 1 ...>, 
#<C id: 3, b_id: 1 ...>, 
#<C id: 4, b_id: 1 ...>

可以找到官方 #becomes(klass(文档 这里!

另一方面,可以达到相同的效果,创建类 B 的实例并为其提供存储在 A.first.b_id 中的 id,如下所示:

B.new(id: A.first.b_id).cs
A Load (0.2ms)  SELECT  "as".* FROM "as" ORDER BY "as"."id" ASC LIMIT ?  [["LIMIT", 1]]
C Load (0.1ms)  SELECT  "cs".* FROM "cs" WHERE "cs"."b_id" = ? LIMIT ?  [["b_id", 1], ["LIMIT", 11]]                 
B.new(id: A.first.b_id).cs ==>#<C id: 1, b_id: 1 ...>, 
#<C id: 2, b_id: 1 ...>, 
#<C id: 3, b_id: 1 ...>, 
#<C id: 4, b_id: 1 ...>

相关内容

最新更新