ryanto/acts_as_votable

Caching is touched updated_at column of votable object

Closed this issue · 1 comments

akeuk commented

I've implemented vote caching like https://github.com/ryanto/acts_as_votable#caching
but my votable updated_at attribute has changed after I vote.

irb(main):088:0> WikiPage.first.updated_at
=> 2015-09-07 11:17:32 UTC
irb(main):089:0> WikiPage.first.liked_by User.first
=> true
irb(main):090:0> WikiPage.first.updated_at
=> 2015-09-07 11:18:01 UTC

With query log

irb(main):088:0> WikiPage.first.updated_at
[2015-09-07 18:17:43] DEBUG ActiveRecord::Base :   WikiPage Load (2.0ms)  SELECT  `wiki_pages`.* FROM `wiki_pages`   ORDER BY `wiki_pages`.`id` ASC LIMIT 1
=> 2015-09-07 11:17:32 UTC
irb(main):089:0> WikiPage.first.liked_by User.first
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :   WikiPage Load (1.0ms)  SELECT  `wiki_pages`.* FROM `wiki_pages`   ORDER BY `wiki_pages`.`id` ASC LIMIT 1
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :   User Load (2.0ms)  SELECT  `users`.* FROM `users`   ORDER BY `users`.`id` ASC LIMIT 1
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :    (0.0ms)  SELECT COUNT(*) FROM `votes`  WHERE `votes`.`votable_id` = 75 AND `votes`.`votable_type` = 'WikiPage' AND `votes`.`voter_id` = 2 AND `votes`.`vote_scope` IS NULL AND `votes`.`voter_type` = 'User'
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :   SQL (0.0ms)  INSERT INTO `votes` (`created_at`, `updated_at`, `votable_id`, `votable_type`, `vote_flag`, `vote_weight`, `voter_id`, `voter_type`) VALUES ('2015-09-07 11:18:01', '2015-09-07 11:18:01', 75, 'WikiPage', 1, 1, 2, 'User')
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :    (1.0ms)  SELECT COUNT(*) FROM `votes`  WHERE `votes`.`votable_id` = 75 AND `votes`.`votable_type` = 'WikiPage' AND `votes`.`vote_scope` IS NULL
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :    (0.0ms)  SELECT COUNT(*) FROM `votes`  WHERE `votes`.`votable_id` = 75 AND `votes`.`votable_type` = 'WikiPage' AND `votes`.`vote_flag` = 1 AND `votes`.`vote_scope` IS NULL
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :    (1.0ms)  SELECT COUNT(*) FROM `votes`  WHERE `votes`.`votable_id` = 75 AND `votes`.`votable_type` = 'WikiPage' AND `votes`.`vote_flag` = 0 AND `votes`.`vote_scope` IS NULL
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :    (1.0ms)  SELECT SUM(`votes`.`vote_weight`) AS sum_id FROM `votes`  WHERE `votes`.`votable_id` = 75 AND `votes`.`votable_type` = 'WikiPage' AND `votes`.`vote_flag` = 1 AND `votes`.`vote_scope` IS NULL
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :    (0.0ms)  SELECT SUM(`votes`.`vote_weight`) AS sum_id FROM `votes`  WHERE `votes`.`votable_id` = 75 AND `votes`.`votable_type` = 'WikiPage' AND `votes`.`vote_flag` = 0 AND `votes`.`vote_scope` IS NULL
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :    (1.0ms)  SELECT SUM(`votes`.`vote_weight`) AS sum_id FROM `votes`  WHERE `votes`.`votable_id` = 75 AND `votes`.`votable_type` = 'WikiPage' AND `votes`.`vote_flag` = 1 AND `votes`.`vote_scope` IS NULL
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :    (0.0ms)  SELECT SUM(`votes`.`vote_weight`) AS sum_id FROM `votes`  WHERE `votes`.`votable_id` = 75 AND `votes`.`votable_type` = 'WikiPage' AND `votes`.`vote_flag` = 0 AND `votes`.`vote_scope` IS NULL
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :   WikiPage Exists (1.0ms)  SELECT  1 AS one FROM `wiki_pages`  WHERE (LOWER(`wiki_pages`.`title`) = LOWER('Test_version') AND `wiki_pages`.`id` != 75 AND `wiki_pages`.`wiki_id` = 2) LIMIT 1
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :   WikiContent Load (3.0ms)  SELECT  `wiki_contents`.* FROM `wiki_contents`  WHERE `wiki_contents`.`page_id` = 75 LIMIT 1
[2015-09-07 18:18:01] DEBUG ActiveRecord::Base :   SQL (1.0ms)  UPDATE `wiki_pages` SET `cached_votes_score` = 5, `cached_votes_total` = 5, `cached_votes_up` = 5, `cached_weighted_score` = 5, `cached_weighted_total` = 5, `updated_at` = '2015-09-07 11:18:01' WHERE `wiki_pages`.`id` = 75
=> true
irb(main):090:0> WikiPage.first.updated_at
[2015-09-07 18:18:04] DEBUG ActiveRecord::Base :   WikiPage Load (1.0ms)  SELECT  `wiki_pages`.* FROM `wiki_pages`   ORDER BY `wiki_pages`.`id` ASC LIMIT 1
=> 2015-09-07 11:18:01 UTC
irb(main):091:0> 

Can I vote without touching updated_at of votable object?

Thanks

This gem uses update_attributes which not only touches the record but also leads to inconsistency when record state is invalid (doesn't pass validation) - in this case vote recorded but column not updated.