新手问题 关联里的 class_name 和 foreign_key 不是重复的吗?

wdrsam · November 13, 2015 · Last by Rei replied at September 05, 2016 · 2463 hits

“Rails 会寻找名为 _id 的外键,其中 是模型类名的小写形式。”

user.rb

has_many :microposts, dependent: :destroy
  has_many :active_relationships, class_name:  "Relationship",
                                  foreign_key: "follower_id",
                                  dependent:   :destroy

既然可以用 foreign_key 指明外键,那 class_name 有什么用啊?

class_name 指定了关联对象应该被哪个类初始化。 一般来说是不用指定的,因为 ROR 可以通过关联对象名称进行推导,但是你这个场景下面是无法通过 active_relationships,推导到 Relationship 的。(默认推导是 active_relationships--》ActiveRelationship) 在比如,你可以有一个导师,很多朋友,但是导师和朋友都是“人”对不对。 你写的时候可能是这么写的:

has_one :mentor, class_name:  "People"
has_many :friends, class_name:  "People"                               

以上也是 无法通过关联对象推导出类名的例子。

意思是 Relationship 的 follower_id 是和 user 的外键吧。要不会冲突。就类似命名空间一样。同时这也是 Rails 的“潜规则”,大家是这么约定的。

3 Floor has deleted

顶楼的 Relationship 和 follower_id 不重复啊。

当与潜规则不符时用的

#4 楼 @rei 呃。我是顶楼吗。

#4 楼 @rei 指明了 class_name,按它解释的意思,那不是就去找 relationship_id 作为外键了吗?但根本没有这个字段啊,总觉得教程里说的这句话是错的。像 2 楼说的那样类似于命名空间,就是说类似 duplicated from: 'XXX' 一样才对,刚试了,去掉这句话就会报错说 name error, uninitialized constant User::active_relationships

#4 楼 @rei 我这么理解对么..新手得鼓起很大勇气才敢说出,原文错了....

编程第一条法则:永远都是你的错 https://ruby-china.org/topics/28046

has_many :active_relationships,按约定应该找 ActiveRelationship,class_name 指定了要找的是 Relationship; has_may 的主体是 User,按约定关联的表应该用 user_id 做外键,foreign_key 指定了 follower_id。

#9 楼 @rei 好吧....我明白了,原来是把 user_id 做外键,理解错位了....一个小打击,一点小收获..谢谢谢谢

因为你的代码里面模型名字和外键名字和约定的不一致,所以才要特别声明。如果不特别声明,Rails 会找不到对应的模型,无法创建关联的。microposts 是按照约定命名的,所以不用特别申明。

#1 楼 @sennmac 谢谢,讲解很清晰。

#9 楼 @Rei ,新手,今天看到 redmine 的 model 中有用到 calss_name,你的解释清晰易懂,看完就明白了,不过还有一点疑问,既然 rails 已经指定了约定,我在 model 关联中直接 has_many :relationships 不可以吗,为什么要用到 class_name 呀?

#13 楼 @seven.lee 可以,我顺着问题的例子解释的。

You need to Sign in before reply, if you don't have an account, please Sign up first.