2012-01-25 1 views
2

Я не могу удалить старые записи из своего приложения на heroku.Удалите старые записи на Heroku (Rails 3.1) с помощью команды rake

В настоящее время планировщик Heroku работает:

class Post < ActiveRecord::Base 

def self.get_data 
    # this populates my app but the database is starting to get large and I don't need the old records 
    scr = Scrape.new 
    data_array = scr.scrape 
    store_data(data_array) 
    # destroy_old_data 
end 

, но я хотел бы, чтобы раскомментировать "destory_old_data" вызов.

def destroy_old_data 
    # oldest = Post.where("updated_at > ?", 30.days.ago) 
    # Post.delete_all("updated_at > ?", 30.days.ago) 
    # Post.destroy_all("updated_at > ?", 30.days.ago) 
    oldest = Post.find(:all, "updated_at > ?", 30.days.ago) 
    oldest.destroy 
end 

Как вы можете видеть, я попробовал несколько вещей, которые, кажется, работают локально в консоли, но я не могу заставить их работать на Heroku.

Ошибки я получаю, как:

ArgumentError: wrong number of arguments (2 for 1) 

or 

when using Post.find 
NoMethodError: undefined method `destroy' for #<Array:0x00000004579898> 

Что это самый простой вызов, я могу сделать, чтобы найти и удалить все эти старые записи успешно?

Любая помощь будет оценена по достоинству.

+0

Вы получаете эту ошибку на 'старейшей = Post.find (: все,«updated_at»...)'? – berkes

+0

Нет, для этого я получаю: NoMethodError: undefined метод 'destroy 'для # AdamT

+0

« oldest »- это массив записей. Вам нужно будет перебирать их, чтобы уничтожить каждого, не так ли? – jstim

ответ

5

Чтобы адресовать NoMethodError, вам необходимо выполнить итерацию по массиву записей и вызвать destroy на каждом из них.

oldest.each { |r| r.destroy } 

или вы можете использовать метод, как destroy_all, где вы даже не нужно делать дополнительную find. http://apidock.com/rails/ActiveRecord/Base/destroy_all/class

Post.destroy_all(['updated_at < ?', 30.days.ago]) 

Ввод условий внутри массива должны решить ArgumentError, как @ Лука-Чедвик отметил в своем ответе.

Один пункт, чтобы рассмотреть с этим, сколько записей вы удаляете (здесь записка от Docs):

Note: Instantiation, callback execution, and deletion of each record can be time consuming when you’re removing many records at once. It generates at least one SQL DELETE query per record (or possibly more, to enforce your callbacks). If you want to delete many rows quickly, without concern for their associations or callbacks, use delete_all instead.

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

+1

Просто указать на ошибку: '' 'оператор не должен использоваться, поскольку это заставит ActiveRecord уничтожить данные _newer than_ 30 дней. Вместо этого используйте '<'. – aldavigdis

+1

спасибо за исправление. – jstim

1

Вы пытаетесь «удалить» массив, список сообщений. Вы должны вызывать удаление для каждого элемента в этом списке.

Post.where(["updated_at > ?", 30.days.ago]).each do |post| 
    post.delete 
end 

Куда принимает один аргумент. И возвращает список сообщений, соответствующих его критериям. Затем вы можете перебрать эти сообщения и выполнить действие (delete) на каждом.

+0

это возвращает пустой массив (что означает: => []). У меня есть сообщения старше 30 дней. делая Post.first возвращает запись с обновленным_at: «2011-12-23 19:01:53» – AdamT

+0

Исправьте меня, если я ошибаюсь, но это будет только возврат сообщений, созданных 30 дней назад, не все сообщения старше, чем 30 дней. –

+0

Вы правы, я скопировал неправильный код из вопроса. Обновлено, чтобы запрос возвращался 'больше, чем 30 дней назад'. – berkes

1

Метод Post.destroy_all принимает все, что может быть передано параметру условий find (: all). Сюда входят строка, хэш или массив.

Если вы показать источник в documentation для уничтожить все, что вы должны увидеть это:

# File activerecord/lib/active_record/base.rb, line 879 
def destroy_all(conditions = nil) 
    find(:all, :conditions => conditions).each { |object| object.destroy } 
end 

Как вы можете видеть, он принимает один аргумент. Таким образом, условия должны быть завернуты в скобки массива (как показано на рисунке):

Post.destroy_all(['updated_at > ?', 30.days.ago]) 
Смежные вопросы