Skip to content

Commit

Permalink
Added validation that each vote has a unique userid, articleid combin…
Browse files Browse the repository at this point in the history
…ation. Made seed file generate a vote for every user and article. Fixed some tabbing issues. Made current_user handle if the no user is found
  • Loading branch information
paulmckissock committed Jun 28, 2024
1 parent d0d5910 commit 27deeb1
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 35 deletions.
7 changes: 6 additions & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ class ApplicationController < ActionController::Base

def current_user
if session[:user_id]
@user = User.find(session[:user_id])
begin
@user = User.find(session[:user_id])
rescue ActiveRecord::RecordNotFound
session[:user_id] = nil
@user = nil
end
end
end

Expand Down
26 changes: 13 additions & 13 deletions app/controllers/articles_controller.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
class ArticlesController < ApplicationController
before_action :authorized, only: [:new, :create]
before_action :set_article, only: [:show, :upvote, :downvote]

def index
@articles = Article.order(created_at: :desc).page(params[:page]).per(20)
@user_votes = Vote.where(user: current_user, votable: @articles.to_a).index_by(&:votable_id)
end

def show
@comments = @article.comments.without_parent.order(created_at: :desc)
@comments = article.comments.without_parent.order(created_at: :desc)
@comment = Comment.new
end

def upvote
vote(1)
respond_to do |format|
format.json { render json: {new_score: @article.score} }
format.json { render json: {new_score: article.score} }
end
end

def downvote
vote(-1)
respond_to do |format|
format.json { render json: {new_score: @article.score} }
format.json { render json: {new_score: article.score} }
end
end

Expand All @@ -31,31 +31,31 @@ def new

def create
@article = Article.new(article_params)
@article.user = current_user
article.user = current_user

if @article.save
redirect_to @article
if article.save
redirect_to article
else
render :new, status: :unprocessable_entity
end
end

private

def set_article
@article = Article.find(params[:id])
def article
@article ||= Article.find(params[:id])
end

def article_params
params.require(:article).permit(:title, :link)
end

def vote(value)
@vote = @article.votes.find_or_initialize_by(user: current_user)
if @vote.value == value
@vote.update(value: 0)
vote = article.votes.find_or_initialize_by(user: current_user)
if vote.value == value
vote.update(value: 0)
else
@vote.update(value: value)
vote.update(value: value)
end
end
end
4 changes: 2 additions & 2 deletions app/models/article.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

class Article < ApplicationRecord
belongs_to :user
has_many :comments
has_many :votes, as: :votable
has_many :comments, dependent: :destroy
has_many :votes, as: :votable, dependent: :destroy

validates :title, presence: true
validates :link, presence: true
Expand Down
2 changes: 1 addition & 1 deletion app/models/comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class Comment < ApplicationRecord
belongs_to :article
belongs_to :user
validates :text, presence: true
has_many :votes, as: :votable
has_many :votes, as: :votable, dependent: :destroy

belongs_to :parent, class_name: "Comment", optional: true
has_many :replies, class_name: "Comment", foreign_key: :parent_id, dependent: :destroy
Expand Down
6 changes: 3 additions & 3 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
class User < ApplicationRecord
has_secure_password
has_many :articles
has_many :comments
has_many :votes
has_many :articles, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :votes, dependent: :destroy

validates :name, presence: true, uniqueness: true
validates :email, presence: true, uniqueness: true, format: {with: URI::MailTo::EMAIL_REGEXP, message: "must be a valid email address"}
Expand Down
1 change: 1 addition & 0 deletions app/models/vote.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ class Vote < ApplicationRecord
belongs_to :votable, polymorphic: true

validates :value, inclusion: {in: [-1, 0, 1]}
validates :user_id, uniqueness: {scope: [:votable_id, :votable_type]}
end
22 changes: 11 additions & 11 deletions app/views/articles/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
<ul>
<% @articles.each do |article| %>
<li>
<div style="display: flex; align-items: center;">
<%= link_to article.title, article.link, target: "_blank" %>
- Score: <span id="score-<%= article.id %>"><%= article.score %></span>
<% user_vote = @user_votes[article.id] %>
<%= button_to "Upvote", upvote_article_path(article), method: :post, class: "btn btn-sm upvote-button", data: { article_id: article.id } %>
<div style="display: flex; align-items: center;">
<%= link_to article.title, article.link, target: "_blank" %>
- Score: <span id="score-<%= article.id %>"><%= article.score %></span>
<% user_vote = @user_votes[article.id] %>
<%= button_to "Upvote", upvote_article_path(article), method: :post, class: "btn btn-sm upvote-button", data: { article_id: article.id } %>
<%= button_to "Downvote", downvote_article_path(article), method: :post, method: :post, class: "btn btn-sm downvote-button", data: { article_id: article.id } %>
</div>
- Posted by <%= link_to article.user.name, user_path(article.user) %> on <%= article.created_at.strftime("%B %d, %Y at %I:%M %p") %>
<div>
<%= link_to "comment", article %>
</div>
<%= button_to "Downvote", downvote_article_path(article), method: :post, method: :post, class: "btn btn-sm downvote-button", data: { article_id: article.id } %>
</div>
- Posted by <%= link_to article.user.name, user_path(article.user) %> on <%= article.created_at.strftime("%B %d, %Y at %I:%M %p") %>
<div>
<%= link_to "comment", article %>
</div>
</li>
<% end %>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

<head>
<title>HaxxorNewsClone</title>
Expand Down
2 changes: 2 additions & 0 deletions db/migrate/20240626175659_create_votes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ def change

t.timestamps
end

add_index :votes, [:user_id, :votable_id, :votable_type], unique: true, name: "index_votes_on_user_and_votable"
end
end
7 changes: 4 additions & 3 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Vote.destroy_all
Comment.destroy_all
Article.destroy_all
User.destroy_all
Expand Down Expand Up @@ -52,11 +53,11 @@
end
# Generate votes for articles
articles.each do |article|
rand(1..5).times do # Random number of votes per article
users.each do |user|
Vote.create!(
votable: article,
user: users.sample,
value: [-1, 0, 1].sample # Randomly selects a vote value
user: user,
value: [-1, 0, 1].sample
)
end
end

0 comments on commit 27deeb1

Please sign in to comment.