Rails - Помощь с граблями - PullRequest
       5

Rails - Помощь с граблями

0 голосов
/ 29 декабря 2010

У меня есть задача rake, которую нужно запустить, чтобы очистить (удалить косую черту) некоторые данные в базе данных. Вот задача:

namespace :db do
  desc "Remove slashes from old-style URLs"
  task :substitute_slashes => :environment do
    puts "Starting"
    contents = Content.all
    contents.each do |c|
      if c.permalink != nil
        c.permalink.gsub!("/","")
        c.save!
      end
    end
    puts "Finished"    
  end
end

Что позволяет мне запустить rake db:substitute_slashes --trace

Если я сделаю puts c.permalink после gsub! Я вижу, что он устанавливает атрибут правильно. Однако сохранить! кажется, не работает, потому что данные не изменились. Может кто-нибудь определить, в чем проблема?

Другое дело, у меня установлена ​​скрепка, и эта задача вызывает [paperclip] Saving attachments., которого я бы предпочел избежать.

Ответы [ 2 ]

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

попробуйте это:

namespace :db do
  desc "Remove slashes from old-style URLs"
  task :substitute_slashes => :environment do
    puts "Starting"
    contents = Content.all
    contents.each do |c|
      unless c.permalink.nil?
        c.permalink = c.permalink.gsub(/\//,'')
        c.save!
      end
    end
    puts "Finished"    
  end
end

1.) Измените! = Nil на разве что record.item.nil? (Я не знаю, изменится ли он, но я никогда не использовал! = Ноль. Вы можете использовать .blank? Также, судя по вашему коду)

2.) Ваш gsub был уродливым. Шаблон должен быть между двумя / (/ вещи /). \ Необходим, потому что вам нужно экранировать /.

3.) Удар (!) Обновляет объект на месте. Я думаю, что вашей самой большой проблемой может быть то, что вы злоупотребляете!

4.) Вы также делаете это очень неэффективным ... Вы просматриваете каждую запись и обновляете каждую запись. Rails не всегда лучший вариант. Изучай SQL и делай это в одну строку:

"UPDATE contents SET permalink = replace(permalink, '/', '');"

Если вы ДОЛЖНЫ использовать Rails:

ActiveRecord::Base.connection.execute "UPDATE contents SET permalink = replace(permalink, '/', '');"

Вау! Один запрос Удивительно! :)

1 голос
/ 29 декабря 2010

Следующее, что я бы попробовал, было бы

c.permalink = c.permalink.gsub("/","")

Что касается сохранения без обратных вызовов, эта страница stackoverflow содержит некоторые предложения.

...