class_name和source

时间:2015-11-22 08:04:12

标签: ruby-on-rails-4

我对class_name的{​​{1}}和source选项之间的区别感到困惑。

对于has_many,API文档中说:

  

指定关联的类名。仅当无法从关联名称推断出该名称时才使用它。所以has_many:产品默认会链接到Product类,但如果真正的类名是SpecialProduct,则必须使用此选项指定它。

对于class_name

  

指定has_many:through查询使用的源关联名称。只有在无法从关联中推断出名称时才使用它。 has_many:订阅者,通过::订阅将寻找订阅者或订阅者订阅者,除非给出:来源。

似乎这两个选项具有相同的功能,即指定关联的类名,但source仅用于source,而has_many :through可以在每个class_name关联中设置。

如果是这样,为什么has_many有必要使用非常相似的函数来设置这两个选项?为什么只使用has_many来指定所有关联名称?

我在很多地方搜索但找不到答案。我还阅读了Rails: difference between :source => ?? and :class_name => ?? in models,但它仍然无法解释为什么class_nameclass_name的存在都是必要的。

提前致谢。

1 个答案:

答案 0 :(得分:3)

关键点是 class_name 指定关联的 类名称 来源指定来源 协会名称

示例:

lass User < ActiveRecord::Base
  has_many :listing_managers
  has_many :managed_listings, through: :listing_managers, source: :listing
end

class Listing < ActiveRecord::Base
  has_many :listing_managers
  has_many :managers, through: :listing_managers, source: :user
end

class ListingManager < ActiveRecord::Base
  belongs_to :listing
  belongs_to :user
end

在上面的代码示例中,userclass_name。当我们声明has_many :managers, through: :listing_managers时,rails会期望与manager or managers中的ListingManager关联。由于我们希望使用user关联来创建managers,因此我们必须告诉它使用ListingManager的managers关联进行user关联。

以下是使用class_name选项

的另一个示例
class User < ActiveRecord::Base
  has_many :listing_managers
  has_many :listings, through: :listing_managers
end

class Listing < ActiveRecord::Base
  has_many :listing_managers
  has_many :managers, through: :listing_managers
end

class ListingManager < ActiveRecord::Base
  belongs_to :listing
  belongs_to :manager, class_name:"User"
end

在上面的代码中,我们在belongs_to :manager上声明ListingManager关联,但没有名为manager的模型,这就是我们必须设置class_name选项的原因。现在,因为我们有manager关联 ListingManager我们不需要在source上设置我们在第一个示例中必须执行的Listing选项。

希望以上将有助于某人。