Rails: Создать ассоциацию, если ничего не найдено, чтобы избежать нулевых ошибок

У меня есть приложение, в котором мои пользователи могут иметь набор настроек. Обе они хранятся как модели ActiveRecord следующим образом:

class User < AR::Base
   has_one :preference_set
end

class PreferenceSet < AR::Base
   belongs_to :user
end

Теперь я могу получить доступ к предпочтениям пользователя:

@u = User.first
@u.preference_set => #<PreferenceSet...>
@u.preference_set.play_sounds => true

Но это не удается, если набор предпочтений еще не создан, поскольку @ u.preference_set будет возвращать nil, а я Я буду вызывать play_sounds на nil .

Я хочу заархивировать, что User.preference_set всегда возвращает экземпляр PreferenceSet. Я пробовал определить его так:

class User < ..
   has_one :preference_set

   def preference_set
     preference_set || build_preference_set
   end
end

Это вызывает «Уровень стека слишком глубокий» , так как он вызывает себя рекурсивно.

Мой вопрос:

Как я могу убедитесь, что @ user.preference_set возвращает либо соответствующую запись набора-предпочтений, либо, если таковой не существует, затем загрузите этот другой файл. Мне нужно поведение, подобное require в Perl, #include в C или execfile в Python при передаче локальных и глобальных переменных текущих модулей, как если бы указанный файл был вставлен непосредственно в текущий сценарий.

Большинство существующих решений, которые я могу найти там, относятся к встраиванию этих "включаемых" внутри тегов сценария, но я не уверен, что это применимо (и если да, то объяснение, где именно мое расширение внедряет все эти теги сценария в текущую страницу).

Update0

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

13
задан Matt Joiner 27 June 2012 в 04:12
поделиться