Rails关联一个表中同一个表的两个外键

时间:2009-12-11 13:31:14

标签: ruby-on-rails associations

我是RoR的新手并且还在玩协会。我需要在另一个模型中有两个对特定模型的引用。脚手架代码不起作用,我得到一个“未初始化的常量”错误。

生成命令:

script/generate scaffold BaseModel name:string
script/generate scaffold NewModel name:string base1:references base2:references
db:migrate

生成的模型:

class NewModel < ActiveRecord::Base
     belongs_to :base1
     belongs_to :base2
end

class BaseModel < ActiveRecord::Base
     has_many :new_models # I added this line
end

当我尝试在/new_models/new创建一个new_model时,我尝试了ID和BaseModel的名称,但它不起作用。我得到的错误是:

uninitialized constant NewModel::Base1

我猜测它会映射名称,所以在我的create方法中,我尝试显式设置BaseModel实例:

@new_model = NewModel.new(params[:new_model])
@base1 = BaseModel.find(1) # this exists
@base2 = BaseModel.find(2) # this exists
@new_model.base1 = @base1  # This throws the same error as above

我有什么遗漏吗?

2 个答案:

答案 0 :(得分:31)

大多数Rails' magic 来自约定优于配置。通过根据指南命名,Rails可以猜测大多数配置选项。 ActiveRecord :: Associations也不例外。

任何ActiveRecord Association的第一个参数是将在模型中使用的名称。这通常是另一个模型的名称,这是惯例。默认情况下,类名是camelcase中关联名称的唯一名称。关联中的默认外键是后缀为“_id”的关联名称。如果您的关联名称与这些模式的类名或外键不匹配,则需要将它们作为选项提供。

这将做你想要的:

class NewModel
  belongs_to :base1, :class_name => "BaseModel"
  belongs_to :base2, :class_name => "BaseModel"
end

就个人而言,我会给协会提供更具描述性的名称base1和base2。像这样:

评级表:id,rater_id,rating_id,评级

class Rating
  belongs_to :rater, :class_name => "User"
  belongs_to :rated_user, :class_name => "User", :foreign_key => "rated_id"
end

可能已经使用了另一个示例,但选择此选项是为了突出显示何时需要外键选项。

答案 1 :(得分:0)

传递给belongs_to方法的符号需要是另一个模型的单数名称。因此,对于您的示例,它将是:

class NewModel < ActiveRecord::Base 
  belongs_to :base_model 
end