我有3个模型。
模型A属于模型B,模型B有许多模型C
通过使用through
我可以在模型A类中设置has_many :c,through: :b
现在,每当我调用a_instance.cs
它会不必要地与表 B 连接 我想要的是直接关联A
和C
在 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 ...>