Создание записи для ассоциации незаметно при попытке доступа? - PullRequest
3 голосов
/ 20 мая 2009

У меня есть простое отношение has_one / own_to между двумя моделями.

Это новое сопоставление в моем приложении, поэтому существует много записей, для которых еще не создана соответствующая запись.

Во всем приложении я предполагаю, что модель имеет связь, и я получаю доступ к ее атрибутам и методам. Однако, поскольку ассоциация не существует, я сталкиваюсь с множеством ошибок.

Что я хотел бы сделать, так это ненавязчиво создавать связанную запись на лету, когда к ней обращаются впервые через любой из ее методов и атрибутов. Неважно, что в записи есть данные, мне просто нужно, чтобы они существовали, чтобы те методы, которые я вызываю, могли создавать данные.

Редактировать: Я не хочу проверять и создавать записи во всех случаях, когда я пытаюсь получить доступ к отношениям, поэтому в идеале это нужно делать на самой модели, а не в мои контроллеры где угодно.

Есть мысли?

Спасибо!

Ответы [ 4 ]

1 голос
/ 21 мая 2009

Вот что мы в итоге сделали, что добились цели. Я не написал это (коллега сделал), но он проходит ранее провальные тесты, которые я написал для этого случая.

def stats_with_create
  stats_without_create || create_stats
end
alias_method_chain :stats, :create
0 голосов
/ 20 мая 2009

Прямой ответ - переопределить метод для отношений. При вызове он проверит, существует ли запись, и создаст ее, если ее нет.

Однако я бы порекомендовал вам использовать миграцию для создания всех записей заранее.

0 голосов
/ 20 мая 2009

Я делал подобные вещи раньше, но не на уровне модели. Я сделал это на уровне контроллера с помощью before_filter, который выполнялся перед всеми методами, которые требовались для доступа к ассоциации моделей, которая существовала или еще не существовала.

Я только что понял, что есть обратные вызовы after_find и after_initialize, которые вы можете использовать в модели.

Вы могли бы придерживаться:

def after_initialize
   association.build if association.nil?
end

в вашей модели, и это должно решить ваши проблемы .. (отказ от ответственности: не проверен мной):)

0 голосов
/ 20 мая 2009

В контроллере вы можете поместить что-то вроде этого в метод show (не проверено, но оно должно дать вам представление:

@thing = Thing.find params[:id]
if @thing.other_thing.nil?
  @thing.other_thing = OtherThing.new.save!
  @thing.save!
end

Это не идеально, и вы, вероятно, могли бы многое очистить, добавив в модель Thing метод, который проверял бы и создавал связанную модель вместо того, чтобы помещать ее в свой контроллер.

Другой вариант - создать новый метод доступа, который вы используете для доступа к other_thing, создав его по мере необходимости.

Тем не менее, правильное решение, вероятно, состоит в том, чтобы исправить ваши данные, либо в процессе миграции, либо напрямую, правильно создав связанные модели.

...