Как добавить метод в приложение Rails, который обновляет коллекцию объектов? - PullRequest
1 голос
/ 08 ноября 2011

У меня есть очень стандартное приложение CRUD в Rails & Jquery Mobile с двумя моделями, относящимися к моему вопросу:

class Wall < ActiveRecord::Base
  has_many   :problems
end

class Problem < ActiveRecord::Base
  # boolean attribute is_live
  belongs_to  :wall
end

Показывая каждую стену, я хватаю каждую проблему, принадлежащую той стене, для которой is_live == true. Теперь моя цель - создать метод для «очистки» стены от всех проблем путем нахождения каждой проблемы на стене с помощью is_live == true и обновления is_live до false.

Однако я не знаю лучших практик / подходов для поиска и обновления каждого из соответствующих объектов. (Это будет ограниченная функция, доступная только тем, у кого есть права администратора). Должен ли я:

  1. Добавить ссылку на сообщения, которые публикуются во вновь созданном действии WallController. как ниже?

    def clear_wall
      @wall = Wall.find(params[:id])
      @problems = @wall.problems.where(:is_live => true)
      @problem.each {|p| p.update_attribute(:is_live => false) }
    
      redirect_to(walls_url)
    end
    
  2. Добавить form_for для отправки того же кода контроллера?

  3. Добавить новый метод в модель стены, чтобы справиться с этим?

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

1 Ответ

2 голосов
/ 09 ноября 2011

Поскольку вам не нужно передавать какие-либо данные на сервер, кроме идентификатора, который будет указан в URL-адресе, поэтому использование link_to должно подойти.

Используйте этот метод POST, используя :method => :post при изменении данных на сервере - изменение данных без POSTing - плохая идея

Если вам не нужен специальный вид, вы также можете использовать :remote => true, чтобы использовать AJAX для отправки формы по этому URL. В противном случае redirect_to в вашем вопросе будет достаточно.

См. Документацию ActionView для получения дополнительной информации о том, как создать link_to

.

Я бы тогда реализовал логику (как показано ниже) в вашем контроллере напрямую

Использование update_all для обновления многих объектов в БД

ActiveRecord имеет метод update_all, который можно вызвать по ActiveRecord::Relation

Он не загружает модели из БД и не вызывает обратные вызовы , но, поскольку установка чего-либо, что не является ложным, ложным, функционально эквивалентно установке всего ложного с его использованием, как это может соответствовать вашей цели

Wall.find(params[:id]).problems.update_all(:is_live => false)

Вы можете указать условный параметр для update_all

Wall.find(params[:id]).problems.update_all(:is_live => false, "is_live = true")

или, альтернативно, сначала выполните команду where, но при этом сначала будут загружены все данные из базы данных, и в вашем случае это не нужно. Здесь важно отметить, что метод update_all работает на ActiveRecord::Relation, а не ActiveRecord::Base

Wall.find(params[:id]).problems.where(:is_live => true).update_all(:is_live => false)

...