2009-07-10 2 views
0

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

def remove_duplicates 
     before = @tweets.size 
     @tweets.delete_if {|tweet| !((Tweet.all :conditions => { :twitter_id => tweet.twitter_id}).empty?) } 
     duplicates = before - @tweets.size 
     puts "#{duplicates} duplicates found" 
    end 

Где @tweets является массив комании объектов извлекается из твиттера. Я был бы признателен за любое решение, которое работает, и особенно тот, который может быть более изящным ...

ответ

2

Вы можете validate_uniqueness_of :twitter_id в модели Tweet (где этот код должен быть). Это приведет к невозможности сохранения дубликатов.

+0

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

+0

@weppos: Поскольку у меня есть только одна последовательная работа над написанием твитов, это не проблема. Это, по-видимому, самое «сухое» решение. Хорошо работал на sqlite3, но в режиме производства/mysql он, похоже, не замечает дубликатов ... глядя в него сейчас. – effkay

+0

для реальной безопасности, вы должны установить ограничения уникальности в базе данных и просто быть готовыми к обработке любых исключений, которые были сброшены –

0

массив.uniq!

Удаляет повторяющиеся элементы из себя. Возвращает nil, если никаких изменений не производится (т. Е. Дубликатов не найдено).

+0

не поможет для дубликатов в базе данных. –

1

Поскольку кажется, что вы используете API поиска в Twitter, лучшим решением является использование параметра since_id. Следите за последним идентификатором статуса Twitter, который вы получили из предыдущего запроса, и используйте его как параметр since_id в следующем запросе.

Более подробная информация доступна на Twitter Search API Method: search

0

Хорошо, оказывается, проблема была немного иной природа: При поиске ближе к ней, я узнал, что твиты были кратными сохранены с twitter_id 2147483647 ... Это верхний предел для целочисленных полей :)

Изменение поля в bigint решило проблему. Мне потребовалось очень много времени, чтобы понять, как MySQL тихо провалился и просто вернулась к максимальному значению, насколько это возможно. (пока не добавлен уникальный индекс). Я быстро опробовал его с помощью postgres, в результате чего появилась хорошая ошибка «Целое вне диапазона», которая затем указала на реальную причину проблемы здесь.

Спасибо Бен за советы по проверке и индексированию, поскольку они приводят к значительно более чистым кодам сейчас!

Смежные вопросы