I have three models User, Post, Vote
I need to doesn’t allow user to vote for his own post.
How I can make this in my models and test this in Rspec?
Post Model:
class Post < ActiveRecord::Base
attr_accessible :title, :main_text, :video, :photo, :tag
validates :title, presence: true, length: {minimum: 1, maximum: 200}
validates :main_text, presence: true, length: {minimum: 1}
belongs_to :user
has_many :votes
end
User Model:
class User < ActiveRecord::Base
attr_accessible :name, :email, :bio
has_many :posts
has_many :votes
validates :name, presence: true, length: {minimum: 1, maximum: 120}
validates :email, presence: true, length: {minimum: 5, maximum: 250}, uniqueness: true,
format: {:with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i}
end
Vote model:
class Vote < ActiveRecord::Base
attr_accessible :user_id, :post_id, :units
belongs_to :user
belongs_to :post
validates :post_id, uniqueness: {scope: :user_id} #does not allow user to vote for the same post twice
end
My spec test for Vote:
require 'spec_helper'
describe Vote do
it "does not allow user to vote for the same post twice" do
user = User.create(name: "Nik", email: "nik@google.com" )
post = Post.create(title: "New Post", main_text: "Many, many, many...")
vote1 = Vote.create(user_id: user.id, post_id: post.id)
vote1.errors.should be_empty
vote2 = Vote.create(user_id: user.id, post_id: post.id)
vote2.errors.should_not be_empty
end
it "does not allow user to vote for his own post" do
user = User.create(name:"Nik", email:"a@a.ru")
post = Post.create(user_id: user.id, title: "New Post", main_text: "Many, many, many...")
vote1 = Vote.create(user_id: user.id, post_id: post.id)
vote1.errors.should_not be_empty
end
end
I’ve not tested the following code so it could not work or even kill your cats but try with a custom validation with add an error if the vote’s user is the same of the post’s user.
Note I return if the user or the post are nil for obvius reasons.
EDIT: Here a possible test, here I’m using FactoryGirl to generate votes. Again this code is not tested (sorry for the pun)