Странная проблема с самореферентной принадлежностью - PullRequest
1 голос
/ 24 октября 2011

У меня очень раздражающая проблема с самообращающейся belongs_to ассоциацией в Rails 3:

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 ]

1 голос
/ 24 октября 2011
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 голос
/ 24 октября 2011

Я решил проблему. Виновным было то, что метод [] был перезаписан в модели, и 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

Извините, вы, ребята, не могли бы, конечно, догадаться.

0 голосов
/ 24 октября 2011

Проблема заключается в том, что вторая находка может попасть в кэш ActiveRecord, который извлекает «неотредактированную», кэшированную запись, а не извлекает обновленную из базы данных.

Кроме того, в вашей ассоциации отсутствует другой конец, будь то has_many или has_one, что, вероятно, не позволяет получить запись при ссылке на parent_locale

Редактировать Два конца отношения не должны использовать один и тот же внешний ключ, belongs_to не должен использовать foreign_key

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...