Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review: Daily Votes #54

Closed
georgiee opened this issue Sep 1, 2012 · 10 comments
Closed

Review: Daily Votes #54

georgiee opened this issue Sep 1, 2012 · 10 comments

Comments

@georgiee
Copy link

georgiee commented Sep 1, 2012

Hi Brady,
thank you for this great work. I appreciate it!

I just changed thumbs_up to a daily voteable version. It`s to less for a pull req but maybe useable for someone.
I added a new index field to hold only the day and used this field as a member of the validate scope and also inside the pg fk. WIll this have any impact on the tally performance or performance in general ?

this is the migration

class AddIndexVotesForDailyVoters < ActiveRecord::Migration
  def change
    #remove old fk we replace it with another version below
    remove_index :votes, :name => "fk_one_vote_per_user_per_entity"
    #add indexable field with day values- no hours, minutes or seconds
    add_column  :votes, 
                :day_created_at,
                :timestamp
    #add the new index additionally based on day_created_at
    add_index   :votes,
                ["voter_id", "voter_type", "voteable_id", "voteable_type", "day_created_at"], 
                :name => "fk_one_vote_per_user_per_entity_per_day", 
                :unique => true
  end
end

and that`s the part in vote.rb

class Vote < ActiveRecord::Base
 #...
  #day_created_at
  validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id, :day_created_at]
  #added
  before_create :record_day_created_at
  def record_day_created_at
    self.day_created_at=DateTime.now.utc.midnight
  end
end
@georgiee
Copy link
Author

georgiee commented Sep 6, 2012

Well, I just realized that the method voted_for? can`t be used for a daily voting. I created another method "voted_for_today?" for this.

config/initializers/thumbs_up.rb

module ThumbsUp
  module ActsAsVoter
    module InstanceMethods
      def voted_for_today?(voteable)
        0 < Vote.where(
          :voter_id => self.id,
          :voter_type => self.class.base_class.name,
          :voteable_id => voteable.id,
          :voteable_type => voteable.class.base_class.name,
          :day_created_at => DateTime.now.utc.midnight
        ).count
      end
    end
  end
end

@bouchard
Copy link
Owner

Looks good! Feel free to add it to the Wiki for anyone else that might like to make a similar adaptation.

@bouchard
Copy link
Owner

And to answer your question, shouldn't have any impact on vote tallying, as you've indexed it correctly.

@turadg
Copy link

turadg commented Nov 18, 2012

@bouchard I have a similar addition for the wiki, but when I click the Wiki tab it redirects to the Code tab. Is the wiki enabled on this repo? Does it need a starter page?

@bouchard
Copy link
Owner

Should be good now, apparently I needed to visit it once for it to be created. Let me know if it works!

@turadg
Copy link

turadg commented Nov 18, 2012

yup! added my example and @georgiee 's

@georgiee
Copy link
Author

I also wondered about the wiki but I had not the time for asking yet. It works now. Thanks for adding turadg!

@boska
Copy link

boska commented Jan 8, 2013

thanks bouchard and georglee for the great work and modify !

apply this perfectly on my work , but if i want to make a "one vote per 5min version" , can you show me some direction. sorry for my poor english and rails skill

@georgiee
Copy link
Author

georgiee commented Jan 8, 2013

Hi boska,
you should be able to accomplish this by changing DateTime.now.utc.midnight to another discrete value representing your timeslot.

For example the following function gives you the nearest time rounded to 5 minutes:

#generate a 5min time slot 
Time.at((Time.now.to_f/300).round * 300)
#2013-01-08 08:35:00 +0100
#2013-01-08 08:40:00 +0100
#2013-01-08 08:45:00 +0100

I think you have to ensure that the generated "time slot" is always ceiling. Simple rounding could be able problem in the edge cases where a user voted just before the next time slot. For example vote A in 00:04:59 and vote B in 00:05:01. If the time slot calculation is wrong the user could be able to make vote B after two seconds. Because of the involved rounding you will hardly get a perfect 5 minute window. If this is important in your use case you need to develop another solution and I guess without involving the fast index based distinction.

Regards George

@boska
Copy link

boska commented Jan 8, 2013

thanks for the advise , i may apply this concept first , and try out for the best accuracy time slot soultion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants