· 2 min read
Screencast: Active Records Reputation System
Downloads in verschiedenen Formaten:
Resourcen:
terminal
[bash]
rails g reputation_system rake db:migrate [/bash]
Gemfile
[ruby]
gem ‘activerecord-reputation-system’, require: ‘reputation_system’ [/ruby]
models/haiku.rb
[ruby]
has_reputation :votes, source: :user, aggregated_by: :sum [/ruby]
models/user.rb
[ruby]
has_many :evaluations, class_name: “RSEvaluation”, as: :source
has_reputation :votes, source: {reputation: :votes, of: :haikus}, aggregated_by: :sum
def voted_for?(haiku) evaluations.where(target_type: haiku.class, target_id: haiku.id).present? end [/ruby]
config/routes.rb
[ruby]
resources :haikus do member { post :vote } end [/ruby]
haikus_controller.rb
[ruby]
def index @haikus = Haiku.find_with_reputation(:votes, :all, order: “votes desc”) end
def vote value = params[:type] == “up” ? 1 : -1 @haiku = Haiku.find(params[:id]) @haiku.add_or_update_evaluation(:votes, value, current_user) redirect_to :back, notice: “Thank you for voting” end [/ruby]
_haiku.html.erb
[html]
| <%= pluralize haiku.reputation_value_for(:votes).to_i, “vote” %> <% if current_user && !current_user.voted_for?(haiku) %> | <%= link_to “up”, vote_haiku_path(haiku, type: “up”), method: “post” %> | <%= link_to “down”, vote_haiku_path(haiku, type: “down”), method: “post” %> <% end %> [/html]
application.html.erb
[html]
<%= current_user.reputation_value_for(:votes).to_i %> [/html]
models/haiku_vote.rb
[ruby]
validates_uniqueness_of :haiku_id, scope: :user_id validates_inclusion_of :value, in: [1, -1] validate :ensure_not_author
def ensure_not_author errors.add :user_id, “is the author of the haiku” if haiku.user_id == user_id end [/ruby]
models/haiku.rb
[ruby]
def self.by_votes select(‘haikus.*, coalesce(value, 0) as votes’). joins(‘left join haiku_votes on haiku_id=haikus.id’). order(‘votes desc’) end
def votes read_attribute(:votes) || haiku_votes.sum(:value) end [/ruby]
models/user.rb
[ruby]
def total_votes HaikuVote.joins(:haiku).where(haikus: {user_id: self.id}).sum(‘value’) end
def can_vote_for?(haiku) haiku_votes.build(value: 1, haiku: haiku).valid? end [/ruby]
haikus_controller.rb
[ruby]
def index @haikus = Haiku.by_votes end
def vote vote = current_user.haiku_votes.new(value: params[:value], haiku_id: params[:id]) if vote.save redirect_to :back, notice: “Thank you for voting.” else redirect_to :back, alert: “Unable to vote, perhaps you already did.” end end [/ruby]
_haiku.html.erb
[html]
| <%= pluralize haiku.votes, “vote” %> <% if current_user && current_user.can_vote_for?(haiku) %> | <%= link_to “up”, vote_haiku_path(haiku, value: 1), method: “post” %> | <%= link_to “down”, vote_haiku_path(haiku, value: -1), method: “post” %> <% end %> [/html]
application.html.erb
[html]
<%= current_user.total_votes %> [/html]