外键class_name

时间:2015-05-05 13:03:56

标签: ruby-on-rails

所以,这是我第一次使用外键,虽然我认为它们正常工作,但我并不理解语法中的class_name部分。是被引用的表所在的class_name吗?

我的代码:

游戏模型:

belongs_to :user, foreign_key: 'white_player_id', class_name: 'User'
belongs_to :user, foreign_key: 'black_player_id', class_name: 'User'

用户模型:

has_many :games, foreign_key: 'white_player_id', class_name: 'Game'
has_many :games, foreign_key: 'black_player_id', class_name: 'Game'

我正在查看:http://ricostacruz.com/cheatsheets/rails-models.html并且在他们的示例中他们已经将belongs_to和has_many的类名指向了Folder类。

belongs_to :parent, :foreign_key => 'parent_id' class_name: 'Folder'
has_many :folders, :foreign_key => 'parent_id', class_name: 'Folder'

那么,这让我相信类名应该指向包含foreign_key的类?我们非常感谢您的一点见解。

2 个答案:

答案 0 :(得分:2)

class_name用于在您使用的方法中使用的类,如果ActiveRecord无法确定它是哪个类。在您的示例中,您不需要class_name,因为您的方法是user,并且将连接到的类是User,ActiveRecord可以自己解决这个问题。

你还有另外一个问题。您有两个同名useruser的关系,这是不可能的。 你可以这样做:

游戏模型:

belongs_to :white_player, foreign_key: 'white_player_id', class_name: 'User'
belongs_to :black_player, foreign_key: 'black_player_id', class_name: 'User'

的usermodel:

has_many :white_games, class_name: 'Game'
has_many :black_games, class_name: 'Game'

答案 1 :(得分:1)

你只是将关系定义为错误:

belongs_to :user, foreign_key: 'white_player_id', class_name: 'User'
belongs_to :user, foreign_key: 'black_player_id', class_name: 'User'
在这种情况下,

game.user会指向white_player_idblack_player_id

belongs_to :white_player, foreign_key: 'white_player_id', class_name: 'User'
belongs_to :black_player, foreign_key: 'black_player_id', class_name: 'User'

class_name是相关对象的类。

foreign_key是指在定义belongs_to关系时定义关系的模型类表。

class Game < ActiveRecord::Base
  belongs_to :white_player, foreign_key: 'white_player_id', class_name: 'User'
  # foreign_key is game.white_player_id
end

所以当我们game.white_player Active Record寻找:

User.find(game.white_player_id)

加入:

在您的第二个示例中,foreign_key中的has_many引用相关表格。

belongs_to :parent, :foreign_key => 'parent_id' class_name: 'Folder'
has_many :folders, :foreign_key => 'parent_id', class_name: 'Folder'

您无需明确指定外键和类名:

class Folder < ActiveRecord::Base
  # ActiveRecord will infer that the class name is Folder
  has_many :folders, foreign_key: 'parent_id'
  # Rails will infer that the foreign_key is parent_id
  belongs_to :parent, class_name: 'Folder'
end

正如您所看到的,ActiveRecord是一个智能cookie,可以推断出类名和外键。

以下是has_manyforeign_keys的简单解释示例:

class User < ActiveRecord::Base
  has_many :unread_messages, -> { where read: false }, 
           foreign_key: 'recipient_id', # refers to messages.recipient_id
           class_name: 'Message'
end 

user.unread_messages将查询表格消息:

SELECT "messages".* FROM "messages" WHERE "messages"."recipient_id" # ...