has_many путем удаления метаданных ассоциации о массовой ассоциации - PullRequest
2 голосов
/ 13 декабря 2010

Эй, Не рельс нуб, но это поставило меня в тупик. Имеет много сквозных ассоциаций в Rails. Когда я массово назначаю вина в винный бар через таблицу ассоциаций (или через) винных списков с чем-то вроде этого.

class WineBarController

  def update

    @winebar = WineBar.find(params[:id])

    @winebar.wines = Wine.find(params[:wine_bar][:wine_ids].split(","))  // Mass assign wines.

    render (@winebar.update_attributes(params[:wine_bar]) ? :update_success : :update_failure) 

  end

end

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

Есть ли способ сделать так, чтобы он не унес все, просто сделайте перечисляемое сравнение массивов и вставьте удалите все изменения. Я чувствую, что это то, что делает рельсы, и я просто упускаю что-то очевидное.

Спасибо.

1 Ответ

2 голосов
/ 13 декабря 2010

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

Если вы используете стандартную настройку rails для своих форм:

<% form_for @wine_bar do |f| %>

Затем вы можете назвать свое обновление следующим образом:

class WineBarController
  def update
    @winebar = WineBar.find(params[:id])
    render (@winebar.update_attributes(params[:wine_bar]) ? :update_success : :update_failure) 
  end
end

Вам не нужно явно обновлять свою запись с помощью params[:wine_bar][:wine_ids], потому что, когда вы обновили ее с помощью params[:wine_bar],wine_ids были включены как часть этого.Надеюсь, это поможет!

ОБНОВЛЕНИЕ: Вы упомянули, что это не работает из-за настройки форм, но вы можете легко это исправить.В вашей форме вы захотите переименовать поле ввода с wine_bar[wine_ids] на wine_bar[wine_ids_string].Затем вам просто нужно создать методы доступа в вашей модели, например:

class WineBar < ActiveRecord::Base
  def wine_ids_string
    wines.map(&:id).join(',')
  end

  def wine_ids_string= id_string
    self.wine_ids = id_string.split(/,/)
  end
end

Первый метод, описанный выше, - это «getter» - он берет список связанных идентификаторов Wine и конвертирует их в строку, которуюФорма может использовать.Следующим методом является «setter», и он принимает строку идентификаторов, разделенных запятыми, и разбивает ее на массив, который принимает wine_ids=.

Вас также может заинтересовать моя статья Динамические элементы форм в Rails , в которых показано, как рельсы формируют входные данные, не ограничиваются атрибутами в записи базы данных.Можно использовать любую пару методов доступа.

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