Пакетное обновление записей в базе данных Ruby on Rails после запуска gsub - PullRequest
0 голосов
/ 25 ноября 2011

Это вопрос из двух частей. Часть 1 спрашивает, правильна ли моя структура (она работает, я просто хочу знать, является ли это подходом Rails). Часть 2 спрашивает, как на самом деле выполнить вопрос в заголовке этого поста, здесь мы идем:

У меня есть следующая структура в моей модели DVD:

def self.remove_parens 
    # we will remove the beginning parentheses from the entries sent to us by the parens method
    @dvds = self.parens # get the entries we need to edit
    @dvds.each do |dvd|
        @newDvds = dvd.title.gsub!(/^\([0-9]*\)/, '')
    end
end

В файле DvdsController:

  def fixer
    @newDvds = Dvd.remove_parens
  end

В фиксере Просмотр файла:

<% 
  @newDvds.each do |dvd| 
    fullText = "#{dvd.title}"
%>

Это прекрасно работает, я вижу результат работы gsub и удаление записей вроде (245) из заголовка.

  1. Это правильный способ делать вещи в Rails? Поместить большую часть кода в модель, а затем заставить контроллер просто вызвать эту функцию?
  2. Я понимаю, что это только распечатывает изменения, а не записывает их обратно в базу данных. Я хочу записать их обратно в базу данных, как бы я это сделал? Может быть, вызвав действие update для @newDvds в контроллере (поскольку модель не знает о методе обновления)?

Socjopata: Я исправил свою модель, основываясь на ваших предложениях:

dvds = self.parens # get the entries we need to edit
dvds.each do |dvd|
    fixedTitle = dvd.title.gsub!(/^\([0-9]*\)/, '') # this prints it out but doesn't change the entries in the table
    dvd.update_attribute(:title, fixedTitle) # this is supposed to update the attribute in the table
end

Но данные не обновляются, данные в таблице все те же.

Что я наконец-то сделал, так это то, что, похоже, помогло:

Dvd.update(dvd.dogTag, { :title => fixedTitle } )

Теперь мне нужно обрезать этот заголовок, так что я решил добавить что-то вроде:

fixedTitle = dvd.title.gsub!(/^\([0-9]*\)/, '').strip!

Ответы [ 2 ]

0 голосов
/ 28 июля 2012

fixedTitle = dvd.title.gsub!(/^\([0-9]*\)/, '').strip! имеет несколько тонких проблем, первая из которых заключается в том, что ваша база данных не обновляется.

gsub! изменяет строку на месте, и это обходит (по состоянию на 3.2.7) способ ActiveRecord узнать, изменился ли экземпляр. Он считает, что экземпляр вашего DVD остается неизменным, и поэтому пропускает обновление базы данных.

Сравните

dvd.title.gsub!(/^\([0-9]*\)/, '')<br> dvd.changed? # => always false if no other changes were made

dvd.title = dvd.title.gsub(/^\([0-9]*\)/, '')<br> dvd.changed? # => true if title was changed

Кроме того, вызов strip! по возвращении gsub! может быть опасным. Если gsub! не делает подстановок, он вернет ноль, и вы будете пытаться вызвать strip! на ноль. В этом случае я думаю, что вы хотите использовать gsub (без!) Вместо.

0 голосов
/ 25 ноября 2011
  1. Да, логика должна быть размещена в модели.
  2. Так что же мешает вам улучшить remove_parens обновлением @dvds? Как

    _instance_of_a_dvd_model.update_attribute (: title, _gsubbed_title)

Кроме того, вам не нужно "@" использовать ваши локальные переменные в модели. Также, почему вы устанавливаете переменную fullText в виде? ты это где-то используешь? Если да, то вы знаете, что ваше мнение должно быть довольно логичным?

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