自我引用的奇怪问题belongs_to

时间:2011-10-24 12:00:50

标签: ruby-on-rails ruby-on-rails-3 activerecord

我对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

但是,我如何确保不触发此方法,而是关联?坦率地说,我甚至不知道为什么调用这个方法,因为我不会将语言环境视为任何地方的数组。此外,此课程中还有其他关联执行工作。

3 个答案:

答案 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