added post voting

This commit is contained in:
albert
2010-02-15 17:45:09 -05:00
parent 80f033f253
commit 9f353c32f4
10 changed files with 112 additions and 19 deletions

View File

@@ -1,6 +1,4 @@
class Comment < ActiveRecord::Base
class VotingError < Exception ; end
class Comment < ActiveRecord::Base
validates_format_of :body, :with => /\S/, :message => 'has no content'
belongs_to :post
belongs_to :creator, :class_name => "User"
@@ -35,7 +33,7 @@ class Comment < ActiveRecord::Base
votes.create(:user_id => user.id)
else
raise VotingError.new("You have already voted for this comment")
raise CommentVote::Error.new("You have already voted for this comment")
end
end
end

View File

@@ -1,4 +1,6 @@
class CommentVote < ActiveRecord::Base
class Error < Exception ; end
belongs_to :comment
belongs_to :user

View File

@@ -12,6 +12,7 @@ class Post < ActiveRecord::Base
has_one :unapproval, :dependent => :destroy
has_one :upload, :dependent => :destroy
has_many :versions, :class_name => "PostVersion", :dependent => :destroy
has_many :votes, :class_name => "PostVote", :dependent => :destroy
attr_accessible :source, :rating, :tag_string, :old_tag_string
module FileMethods
@@ -140,7 +141,7 @@ class Post < ActiveRecord::Base
self.source = version.source
self.rating = version.rating
self.tag_string = version.tag_string
save
save!
end
end
@@ -473,6 +474,26 @@ class Post < ActiveRecord::Base
end
end
module VoteMethods
def can_be_voted_by?(user)
!votes.exists?(["user_id = ?", user.id])
end
def vote!(user, is_positive)
if can_be_voted_by?(user)
if is_positive
increment!(:score)
else
decrement!(:score)
end
votes.create(:user_id => user.id)
else
raise PostVote::Error.new("You have already voted for this comment")
end
end
end
include FileMethods
include ImageMethods
include ModerationMethods
@@ -483,6 +504,7 @@ class Post < ActiveRecord::Base
include UploaderMethods
include PoolMethods
extend SearchMethods
include VoteMethods
def reload(options = nil)
super

5
app/models/post_vote.rb Normal file
View File

@@ -0,0 +1,5 @@
class PostVote < ActiveRecord::Base
class Error < Exception ; end
belongs_to :post
end

View File

@@ -14,10 +14,6 @@ class User < ActiveRecord::Base
after_save :update_cache
scope :named, lambda {|name| where(["lower(name) = ?", name])}
def can_update?(object, foreign_key = :user_id)
is_moderator? || is_admin? || object.__send__(foreign_key) == id
end
module NameMethods
module ClassMethods
def find_name(user_id)
@@ -100,5 +96,9 @@ class User < ActiveRecord::Base
include PasswordMethods
extend AuthenticationMethods
include FavoriteMethods
def can_update?(object, foreign_key = :user_id)
is_moderator? || is_admin? || object.__send__(foreign_key) == id
end
end

View File

@@ -655,6 +655,38 @@ CREATE SEQUENCE post_versions_id_seq
ALTER SEQUENCE post_versions_id_seq OWNED BY post_versions.id;
--
-- Name: post_votes; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE post_votes (
id integer NOT NULL,
post_id integer NOT NULL,
user_id integer NOT NULL,
created_at timestamp without time zone,
updated_at timestamp without time zone
);
--
-- Name: post_votes_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE post_votes_id_seq
START WITH 1
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
--
-- Name: post_votes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE post_votes_id_seq OWNED BY post_votes.id;
--
-- Name: posts; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@@ -1145,6 +1177,13 @@ ALTER TABLE pools ALTER COLUMN id SET DEFAULT nextval('pools_id_seq'::regclass);
ALTER TABLE post_versions ALTER COLUMN id SET DEFAULT nextval('post_versions_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE post_votes ALTER COLUMN id SET DEFAULT nextval('post_votes_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -1352,6 +1391,14 @@ ALTER TABLE ONLY post_versions
ADD CONSTRAINT post_versions_pkey PRIMARY KEY (id);
--
-- Name: post_votes_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY post_votes
ADD CONSTRAINT post_votes_pkey PRIMARY KEY (id);
--
-- Name: posts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@@ -1913,4 +1960,6 @@ INSERT INTO schema_migrations (version) VALUES ('20100214080605');
INSERT INTO schema_migrations (version) VALUES ('20100215182234');
INSERT INTO schema_migrations (version) VALUES ('20100215213756');
INSERT INTO schema_migrations (version) VALUES ('20100215213756');
INSERT INTO schema_migrations (version) VALUES ('20100215223541');

View File

@@ -0,0 +1,13 @@
class CreatePostVotes < ActiveRecord::Migration
def self.up
create_table :post_votes do |t|
t.column :post_id, :integer, :null => false
t.column :user_id, :integer, :null => false
t.timestamps
end
end
def self.down
drop_table :post_votes
end
end

View File

@@ -38,7 +38,7 @@ class CommentTest < ActiveSupport::TestCase
post = Factory.create(:post)
c1 = Factory.create(:comment, :post => post)
assert_nothing_raised {c1.vote!(user, true)}
assert_raise(Comment::VotingError) {c1.vote!(user, true)}
assert_raise(CommentVote::Error) {c1.vote!(user, true)}
assert_equal(1, CommentVote.count)
c2 = Factory.create(:comment, :post => post)

View File

@@ -1,8 +0,0 @@
require 'test_helper'
class CommentVoteTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end

View File

@@ -405,4 +405,16 @@ class PostTest < ActiveSupport::TestCase
assert_equal(post3.id, relation.first.id)
end
end
context "Voting on a post" do
should "not allow duplicate votes" do
user = Factory.create(:user)
post = Factory.create(:post)
assert_nothing_raised {post.vote!(user, true)}
assert_raise(PostVote::Error) {post.vote!(user, true)}
post.reload
assert_equal(1, PostVote.count)
assert_equal(1, post.score)
end
end
end