Question

I'm creating an hit counter for my webapp using redis and Rails.

I'm saving views in Redis and then, every day, I update the value in the db.

To increase the views I use this method:

  def self.async_increase_visits
    $redis.hkeys('video_visits').each do |id|
      self.find(id).increase_visit($redis.hget('video_visits', id))
      $redis.hdel('video_visits', id)
    end
  end

  def increase_visit(visits)
    self.increment!(:impressions_count, visits.to_i)
  end

I notice that the resulting query is:

Loading staging environment (Rails 4.0.0)
2.0.0-p353 :001 > Content.async_increase_visits
  Content Load (5.1ms)  SELECT "contents".* FROM "contents" WHERE "contents"."id" = $1 ORDER BY published_at DESC LIMIT 1  [["id", "12300"]]
   (0.3ms)  BEGIN
  ContentElement Load (7.8ms)  SELECT "content_elements".* FROM "content_elements" WHERE "content_elements"."content_id" = $1 ORDER BY "content_elements".position ASC  [["content_id", 12300]]
  SQL (15.7ms)  UPDATE "contents" SET "impressions_count" = $1, "updated_at" = $2 WHERE "contents"."type" IN ('News') AND "contents"."id" = 12300  [["impressions_count", 3], ["updated_at", Fri, 02 May 2014 18:58:30 CEST +02:00]]
  SQL (15.5ms)  UPDATE "comments" SET "commentable_state" = 'published', "commentable_url" = '#' WHERE "comments"."id" IN (SELECT "comments"."id" FROM "comments" WHERE "comments"."commentable_id" = $1 AND "comments"."commentable_type" = $2 ORDER BY comments.created_at asc)  [["commentable_id", 12300], ["commentable_type", "Content"]]
   (1.7ms)  COMMIT
 => ["12300"]
2.0.0-p353 :002 > Content.async_increase_visits
  Content Load (1.1ms)  SELECT "contents".* FROM "contents" WHERE "contents"."id" = $1 ORDER BY published_at DESC LIMIT 1  [["id", "12448"]]
   (0.2ms)  BEGIN
  ContentElement Load (0.8ms)  SELECT "content_elements".* FROM "content_elements" WHERE "content_elements"."content_id" = $1 ORDER BY "content_elements".position ASC  [["content_id", 12448]]
  SQL (2.9ms)  UPDATE "contents" SET "impressions_count" = $1, "updated_at" = $2 WHERE "contents"."type" IN ('News') AND "contents"."id" = 12448  [["impressions_count", 2], ["updated_at", Fri, 02 May 2014 18:59:10 CEST +02:00]]
  SQL (4.7ms)  UPDATE "comments" SET "commentable_state" = 'published', "commentable_url" = '#' WHERE "comments"."id" IN (SELECT "comments"."id" FROM "comments" WHERE "comments"."commentable_id" = $1 AND "comments"."commentable_type" = $2 ORDER BY comments.created_at asc)  [["commentable_id", 12448], ["commentable_type", "Content"]]
   (1.2ms)  COMMIT
 => ["12448"]

My content has many comments (polymorfic association) but I don't understand why for a simple "Increment" I update also some value in the association.

How can I update just the impressions_count value?

Was it helpful?

Solution

The increment! method invokes callbacks. If you need just update this column skipping callbacks and validations, you can use update_counters method.

http://api.rubyonrails.org/classes/ActiveRecord/CounterCache/ClassMethods.html#method-i-update_counters

def increase_visit(visits)
  Content.update_counters(self.id, impressions_count: visits.to_i)
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top