Ответ 1
Есть ли способ избежать автоматического обновления полей метки времени Rails?
Или ближе к вашему вопросу:
http://blog.bigbinary.com/2009/01/21/override-automatic-timestamp-in-activerecord-rails.html
Как я могу это достичь?
попытался создать 2 метода, называемых
def disable_timestamps
ActiveRecord::Base.record_timestamps = false
end
def enable_timestamps
ActiveRecord::Base.record_timestamps = true
end
и самого метода обновления:
def increment_pagehit
update_attribute(:pagehit, pagehit+1)
end
Включение и выключение временных меток с помощью обратных вызовов, таких как:
before_update :disable_timestamps, :only => :increment_pagehit
after_update :enable_timestamps, :only => :increment_pagehit
но он ничего не обновляет, даже желаемый атрибут (pagehit).
Любые советы? Я не хочу создавать другую таблицу только для подсчета изображений на странице.
Есть ли способ избежать автоматического обновления полей метки времени Rails?
Или ближе к вашему вопросу:
http://blog.bigbinary.com/2009/01/21/override-automatic-timestamp-in-activerecord-rails.html
В качестве альтернативы update_attribute
, в Rails 3.1+ вы можете использовать update_column
.
update_attribute
пропускает проверки, но коснется updated_at
и выполнит обратные вызовы.
update_column
пропускает проверки, не касается updated_at
и не выполняет обратные вызовы.
Таким образом, update_column
- отличный выбор, если вы не хотите влиять на updated_at
и не нуждаетесь в обратных вызовах.
Подробнее см. http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html.
Также обратите внимание, что update_column
обновит значение атрибута в модели в памяти и не будет помечено как грязное. Например:
p = Person.new(:name => "Nathan")
p.save
p.update_column(:name, "Andrew")
p.name == "Andrew" # True
p.name_changed? # False
Если все, что вы хотите сделать, это увеличить счетчик, я бы использовал вместо этого метод increment_counter
:
ModelName.increment_counter :pagehit, id
Чтобы избежать Monkeypatchingtroubles, вы также можете использовать ModelName.update_all для этой цели:
def increment_pagehit
self.class.update_all({ pagehit: pagehit+1 }, { id: id })
end
Это также не касается временных меток в записи.
не рекомендуется делать это:
self.class.update_all({ pagehit: pagehit+1 }, { id: id })
он должен быть
self.class.update_all("pagehit = pagehit + 1", { id: id })
причина в том, что если два запроса параллельны, в первой версии оба будут обновлять идентификаторы страниц с тем же номером, так как он использует номер, сохраненный в памяти Ruby. Второй вариант использует sql-сервер для увеличения числа на 1, в случае, если два из этих запросов приходят одновременно, сервер будет обрабатывать их один за другим и в итоге будет иметь правильное количество страниц.
У вас также есть decrement
и increment
(и их версии), которые не изменяют updated_at
, не запускают проверки обратных вызовов проверки и, очевидно, удобны для счетчиков/целых чисел.
Если точность не так важна, и вы не ожидаете, что код будет работать много раз, вы можете попробовать изменить сохраненное в базе данных значение updated_at
, например:
u = User.first
u.name = "Alex 2" # make some changes...
u.updated_at = u.updated_at + 0.000001.second # alter updated_at
u.save
чтобы Rails фактически попытался сохранить одно и то же значение, а не заменить его на Time.now
.