Rails сложная форма редактирования нескольких записей одновременно с ассоциациями - PullRequest
3 голосов
/ 26 января 2010

Я разрабатываю сложную форму, которая обновляет несколько записей одной модели одновременно, одновременно обновляя связанную модель. Это выглядит примерно так:

class Sport
  has_one :photo
end

class Photo
  belongs_to :sport
  acts_as_fleximage
end

class Page
  # the page is not related to either of the previous models
end

Просто для небольшого количества справочной информации, модель Page - это общая модель, для которой пользователи смогут создавать столько, сколько им нравится (CMS). Кроме того, они получают небольшое количество обязательных «системных» страниц при регистрации. Когда они пытаются редактировать системную страницу, форма немного отличается от обычной формы страницы.

Одна из системных страниц - это страница «Спорт». Где они могут добавить текст для каждого вида спорта (сохраненный в модели «спорт») и загрузить фотографию (сохраненную в модели «фото»).

Я создал форму, которая, кажется, делает свое дело. Я не буду публиковать представление, но вот пример параметров, которые он отправляет:

:id => 1
:page => {"title"=>"Our sports"}
:sport => {
  "1" => {
    "description" => "<p>I love playing hockey...</p>"
    "photo_attributes" => {
      "image_file" => #<File:/tmp/RackMultipart20100126-955-k0gxu8-0>,
      "description" => "Me in my hockey kit"
    }
  },
  "2" => { #more of the same}
}

Теперь, чтобы сохранить все это, мой контроллер / действие выглядит примерно так:

def update_sports_page
  @page = Page.find params[:id]
  @page.update_attributes params[:page]
  Sport.update(params[:sport].keys, params[:sport].values)
  redirect_to #etc
end

Теперь, когда я редактирую спортивную страницу, все сохраняется и обновляется правильно, ЗА ИСКЛЮЧЕНИЕМ, если я изменю фотографию, а не обновлю существующую запись в базе данных, она просто создаст новую запись и установит sport_id для старая запись на NULL.

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

Кто-нибудь может заметить, что я здесь делаю неправильно?

(ps, если это актуально, я использую fleximage на модели Photo)

1 Ответ

1 голос
/ 26 января 2010

Это, вероятно, правильное поведение, поскольку эта связь установлена: по умолчанию =>: обнулять, а не: зависимо =>: уничтожать.

Возможно, это можно исправить с помощью:

class Photo
  belongs_to :sport,
    :dependent => :destroy
end

Это должно автоматически удалить бесхозные записи.

Вам также следует соблюдать осторожность, чтобы перехватывать исключения при выполнении любой операции поиска или обновления.

def update_sports_page
  @page = Page.find params[:id]
  @page.update_attributes params[:page]

  params[:sport].each do |sport_id, sport_params|
    sport = Sport.find(sport_id)
    sport.update_attributes!(sport_params)
  end

  redirect_to #etc
rescue ActiveRecord::RecordNotFound
  render(:partial => 'page_not_found', :status => :not_found)
rescue ActiveRecord::RecordInvalid
  render(:action => 'edit')
end

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

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