如何强制has_many使用特定的:foreign_key?

时间:2011-08-05 01:54:24

标签: ruby-on-rails ruby activerecord

我遇到了一个不遵守:foreign_key政策的模型的问题。

字符模型具有以下字段: 名称:字符串 级别:INT 境界:字符串 realm_id:整数

class Character < ActiveRecord::Base
  belongs_to :realm

end

My Realms模型如下所示:

class Realm < ActiveRecord::Base
  has_many :characters, :foreign_key => "realm_id"

end

然而,似乎它迫使角色模型使用:realm列作为foreign_key而不是:realm_id。我没有任何关于为什么或如何解决它的线索。有没有其他方法可以忽略:realm字段并转到:realm_id而不必更改列的名称?

[为了清晰起见而编辑]

字符模型确实有一个realm_id:整数字段。我试过没有foreign_key,但两者的结果完全相同。

ruby​​-1.9.2-p136:012&gt; c = Character.new  =&GT; #

ruby​​-1.9.2-p136:013&gt; c.realm =“萨格拉斯”

ActiveRecord :: AssociationTypeMismatch:Realm(#2154038240)预期,得到字符串(#2151988680)

尽管有了foreign_key,但它只是拒绝放弃领域列。

[编辑2]

由于has_many和belongs_to关联,realm列将接管。到目前为止,没有办法打破这一点,所以解决方案是删除列(我将采取的方法),或将其重命名为不同的。

3 个答案:

答案 0 :(得分:1)

您确定您的角色表有 realm_id 列吗?请确保这一点,然后摆脱 foreign_key =&gt; 'realm_id ,根本没有必要。如果你完成这两件事,你的程序应该可以工作。

答案 1 :(得分:0)

您根本不需要:foreign_key部分,因为您遵循标准的Rails命名约定,应该从模型名称推断出realm_id列。

修改

我明白了。我认为您不能在一个模型中使用相同名称的列和关联。最简单的解决方案可能是将“领域”列重命名为“realmname”或类似名称。

答案 2 :(得分:0)

belongs_to :realm创建(除此之外)名为realmrealm=的方法,用作getter和setter。这意味着当您执行Character#realm时,ActiveRecord用于将数据库列作为属性公开的method_missing魔法永远不会被触发,因为该方法实际上并没有丢失。

如果要避免重命名数据库中的realm列,可以使用其他名称手动为该字段创建属性访问器:

class Character < ActiveRecord::Base
  def realm_name
    self['realm']
  end

  def realm_name=(value)
    self['realm'] = value
  end
end

这样,您仍然可以在数据库中拥有realm列,并且能够访问Ruby中的属性,尽管名称不同。但是,这不是一个好主意,因为您将域名重复为Character#realm_nameCharacter.realm.name

我会放弃realm列,而是确保从数据源导入时使用Realm个对象:

character.realm = Realm.find_by_name('Sargeras')

这样你只有在有意义的地方可以使用领域数据;在Realm模型中。