about summary refs log tree commit diff stats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/main/entries.scss10
-rw-r--r--app/controllers/blogs_controller.rb48
-rw-r--r--app/models/blog.rb1
-rw-r--r--app/models/concerns/votable.rb43
-rw-r--r--app/models/vote.rb6
-rw-r--r--app/views/blogs/_blog.html.haml4
-rw-r--r--app/views/blogs/voted.js.erb12
7 files changed, 124 insertions, 0 deletions
diff --git a/app/assets/stylesheets/main/entries.scss b/app/assets/stylesheets/main/entries.scss index edf1706..3b7215c 100644 --- a/app/assets/stylesheets/main/entries.scss +++ b/app/assets/stylesheets/main/entries.scss
@@ -416,3 +416,13 @@
416 font-weight: bold; 416 font-weight: bold;
417 } 417 }
418} 418}
419
420.post-vote {
421 float: right;
422 position: relative;
423 right: 0.5em;
424
425 a {
426 text-decoration: none;
427 }
428}
diff --git a/app/controllers/blogs_controller.rb b/app/controllers/blogs_controller.rb index 0d218ae..2f9df49 100644 --- a/app/controllers/blogs_controller.rb +++ b/app/controllers/blogs_controller.rb
@@ -38,4 +38,52 @@ class BlogsController < ApplicationController
38 }) 38 })
39 end 39 end
40 40
41 def upvote
42 @blog = Blog.find_by_slug(params[:slug])
43
44 raise ActiveRecord::RecordNotFound unless @blog
45 raise ActiveRecord::RecordNotFound unless @blog.published
46
47 respond_to do |format|
48 if @blog.upvote! request.remote_ip
49 format.html do
50 flash[:notice] = "You have upvoted the blog post \"#{@blog.title}\"."
51 redirect_to @blog
52 end
53 format.js { render "voted" }
54 format.xml { head :ok }
55 else
56 format.html do
57 flash[:notice] = "You have already voted on the blog post \"#{@blog.title}\"."
58 redirect_to @blog
59 end
60 format.xml { render :xml => { :error => "Someone from your IP address has already voted on this blog post."} }
61 end
62 end
63 end
64
65 def downvote
66 @blog = Blog.find_by_slug(params[:slug])
67
68 raise ActiveRecord::RecordNotFound unless @blog
69 raise ActiveRecord::RecordNotFound unless @blog.published
70
71 respond_to do |format|
72 if @blog.downvote! request.remote_ip
73 format.html do
74 flash[:notice] = "You have downvoted the blog post \"#{@blog.title}\"."
75 redirect_to @blog
76 end
77 format.js { render "voted" }
78 format.xml { head :ok }
79 else
80 format.html do
81 flash[:notice] = "You have already voted on the blog post \"#{@blog.title}\"."
82 redirect_to @blog
83 end
84 format.xml { render :xml => { :error => "Someone from your IP address has already voted on this blog post."} }
85 end
86 end
87 end
88
41end 89end
diff --git a/app/models/blog.rb b/app/models/blog.rb index 6db75ec..03643bf 100644 --- a/app/models/blog.rb +++ b/app/models/blog.rb
@@ -1,5 +1,6 @@
1class Blog < ApplicationRecord 1class Blog < ApplicationRecord
2 include Recordable 2 include Recordable
3 include Votable
3 4
4 acts_as_taggable 5 acts_as_taggable
5 6
diff --git a/app/models/concerns/votable.rb b/app/models/concerns/votable.rb new file mode 100644 index 0000000..ba6e6d5 --- /dev/null +++ b/app/models/concerns/votable.rb
@@ -0,0 +1,43 @@
1module Votable
2 extend ActiveSupport::Concern
3
4 included do
5 has_many :votes, as: :votable
6
7 def already_upvoted?(ip)
8 !votes.where(ip: ip, upvote: 1).empty?
9 end
10
11 def already_downvoted?(ip)
12 !votes.where(ip: ip, upvote: 0).empty?
13 end
14
15 def upvote!(ip)
16 return false if already_upvoted?(ip)
17
18 if already_downvoted?(ip)
19 votes.where(ip: ip, upvote: 0).first.delete
20 self.downvotes -= 1
21 save!
22 else
23 votes.create(ip: ip, upvote: 1).save
24 self.upvotes += 1
25 save!
26 end
27 end
28
29 def downvote!(ip)
30 return false if already_downvoted?(ip)
31
32 if already_upvoted?(ip)
33 votes.where(ip: ip, upvote: 1).first.delete
34 self.upvotes -= 1
35 save!
36 else
37 votes.create(ip: ip, upvote: 0).save
38 self.downvotes += 1
39 save!
40 end
41 end
42 end
43end
diff --git a/app/models/vote.rb b/app/models/vote.rb new file mode 100644 index 0000000..e2d8386 --- /dev/null +++ b/app/models/vote.rb
@@ -0,0 +1,6 @@
1class Vote < ApplicationRecord
2 belongs_to :votable, polymorphic: true
3
4 validates :upvote, presence: true, inclusion: { in: [0, 1] }
5 validates :ip, presence: true
6end
diff --git a/app/views/blogs/_blog.html.haml b/app/views/blogs/_blog.html.haml index ec61bb5..1f86ae8 100644 --- a/app/views/blogs/_blog.html.haml +++ b/app/views/blogs/_blog.html.haml
@@ -19,3 +19,7 @@
19 %strong= blog.user.login.capitalize 19 %strong= blog.user.login.capitalize
20 on 20 on
21 = blog.visible_date.strftime("%B #{blog.visible_date.day.ordinalize}, %Y at %-I:%M:%S%P") 21 = blog.visible_date.strftime("%B #{blog.visible_date.day.ordinalize}, %Y at %-I:%M:%S%P")
22 .post-vote{ id: "blog-vote-section-#{blog.id}" }
23 %span.vote-link{ id: "blog-upvote-link-#{blog.id}" }= link_to_unless (not blog.published or blog.already_upvoted?(request.remote_ip)), "👍", upvote_blog_path(blog), remote: true, rel: "nofollow", class: "blog-upvote-link", method: :post
24 %span.post-rating{ id: "blog-rating-#{blog.id}" }= blog.upvotes - blog.downvotes
25 %span.vote-link{ id: "blog-downvote-link-#{blog.id}" }= link_to_unless (not blog.published or blog.already_downvoted?(request.remote_ip)), "👎", downvote_blog_path(blog), remote: true, rel: "nofollow", class: "blog-downvote-link", method: :post
diff --git a/app/views/blogs/voted.js.erb b/app/views/blogs/voted.js.erb new file mode 100644 index 0000000..951c740 --- /dev/null +++ b/app/views/blogs/voted.js.erb
@@ -0,0 +1,12 @@
1$("#blog-rating-<%= @blog.id %>").html('<%= escape_javascript("#{@blog.upvotes - @blog.downvotes}") %>');
2
3<% if @blog.already_upvoted? request.remote_ip %>
4 $("#blog-upvote-link-<%= @blog.id %>").html("👍");
5<% elsif @blog.already_downvoted? request.remote_ip %>
6 $("#blog-downvote-link-<%= @blog.id %>").html("👎");
7<% else %>
8 $("#blog-upvote-link-<%= @blog.id %>").html('<%= escape_javascript(link_to("👍", upvote_blog_path(@blog), remote: true, rel: "nofollow", class: "blog-upvote-link", method: :post)) %>');
9 $("#blog-downvote-link-<%= @blog.id %>").html('<%= escape_javascript(link_to("👎", downvote_blog_path(@blog), remote: true, rel: "nofollow", class: "blog-downvote-link", method: :post)) %>');
10<% end %>
11
12$("#blog-vote-section-<%= @blog.id %>").effect('highlight', {}, 2000);