Как установить значение недавно добавленного кеша счетчика ActiveRecord? - PullRequest
0 голосов
/ 20 апреля 2009

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

Изменение количества дочерних элементов обновило кэш счетчика (как и должно быть), а удаление «: counter_cache => true» из дочернего элемента позволило бы мне обновить значение родительского элемента. Но это обман. Мне нужно было иметь возможность добавить кэш счетчика, а затем установить его начальное значение для числа дочерних элементов в миграции, чтобы затем можно было начинать с правильных значений для страниц, которые отображали бы его.

Какой правильный способ сделать это, чтобы ActiveRecord не перекрывал меня?

Ответы [ 2 ]

2 голосов
/ 20 апреля 2009

Вы хотите использовать метод update_counters, этот пост в блоге содержит больше деталей:

http://josh.the -owens.com / Архивы / 2007/11/03 / рельсы края с изменением как к АДД-а-счетчик-кэш-к-ан-существующей-DB-таблицы /

Это RailsCasts по теме тоже хороший ресурс:

http://railscasts.com/episodes/23-counter-cache-column

0 голосов
/ 16 сентября 2018

Каноническим способом является использование reset_counter_cache, т. Е .:

Author.find_each do |author|
  Author.reset_counter_cache(author.id, :books)
end

... и вот как вы должны это делать, если эти таблицы имеют скромный размер, т.е. е. <= 1 000 000 строк. </p>

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

Вот способ сделать это примерно на 5 порядков быстрее:

Author
  .joins(:books)
  .select("authors.id, authors.books_count, count(books.id) as count")
  .group("authors.id")
  .having("authors.books_count != count(books.id)")
  .pluck(:id, :books_count, "count(books.id)")
  .each_with_index do |(author_id, old_count, fixed_count), index| 
    puts "at index %7i: fixed author id %7i, new books_count %4i,  previous count %4i" % [index, author_id, fixed_count, old_count] if index % 1000 == 0
    Author.update_counters(author_id, books_count: fixed_count - old_count)
  end

Также возможно сделать это напрямую в SQL, используя только один запрос, но вышеописанное сработало достаточно хорошо для меня. Обратите внимание на несколько запутанный способ использования разницы предыдущего счета с правильным: это необходимо, потому что update_counters не позволяет установить абсолютное значение, а только увеличивает / уменьшает его. В противном случае столбец помечается только для чтения.

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