我对Rails 3中的自引用belongs_to
关联有一个非常恼人的问题:
class Locale < ActiveRecord::Base
belongs_to :parent_locale, :class_name => 'Locale', :foreign_key => 'parent_locale_id'
end
在控制台中:
locale = Locale.find(2)
locale.parent_locale = Locale.find(3)
locale.save
#----> Association is saved correctly!
locale.parent_locale_id
=> 3
locale.parent_locale
#----> Association is returned correctly!
# Now let's retrieve the record again, and see if it still works...
locale = Locale.find(2)
locale.parent_locale_id
=> 3
locale.parent_locale
=> nil
在地球上可能是什么问题?有什么建议吗?
修改:这也不起作用:
belongs_to :parent_locale, :class_name => 'Locale', :foreign_key => 'parent_locale_id', :inverse_of => :child_locales
has_many :child_locales, :class_name => 'Locale', :foreign_key => 'parent_locale_id', :inverse_of => :parent_locale
编辑:我在控制台中启用了SQL查询日志记录,并注意到当我尝试检索parent_locale
时会发生什么:
locale.parent_locale
Phrase Load (0.4ms) SELECT `phrases`.* FROM `phrases` WHERE `phrases`.`key` = 'parent_locale_id' LIMIT 1
=> nil
哇,这是什么?事实证明Locale
具有以下方法:
def [](key)
if phrase = Phrase.find_by_key(key)
t = self.translations.find_by_phrase_id(phrase.id)
t.text if t
end
end
但是,我如何确保不触发此方法,而是关联?坦率地说,我甚至不知道为什么调用这个方法,因为我不会将语言环境视为任何地方的数组。此外,此课程中还有其他关联执行工作。
答案 0 :(得分:1)
belongs_to :parent_locale, :class_name => 'Locale', :foreign_key => 'parent_locale_id'
has_many :child_locales, :class_name => 'Locale', :foreign_key => 'parent_locale_id'
答案 1 :(得分:1)
我解决了这个问题。罪魁祸首是模型中覆盖了[]
方法,Rails似乎用它来访问模型的外键列。
我不得不改变这个......
def [](key)
if phrase = Phrase.find_by_key(key)
t = self.translations.find_by_phrase_id(phrase.id)
t.text if t
end
end
到此:
def [](key)
if phrase = Phrase.find_by_key(key)
t = self.translations.find_by_phrase_id(phrase.id)
t.text if t
else
super(key)
end
end
对不起,你们当然不能猜到这一点。
答案 2 :(得分:0)
问题是,第二个查找可能是命中ActiveRecord的缓存,它正在检索“未编辑的”缓存记录,而不是从数据库中检索更新的缓存。
此外,您的关联缺少另一端,无论是has_many
还是has_one
,这可能会阻止在引用parent_locale
修改关系的两端不应使用相同的外键,belongs_to
不应使用foreign_key