Skip to content

Instantly share code, notes, and snippets.

@danielsousaio
Last active October 27, 2017 22:18
Show Gist options
  • Save danielsousaio/d44109441e04fee0475c80fc0785e3e4 to your computer and use it in GitHub Desktop.
Save danielsousaio/d44109441e04fee0475c80fc0785e3e4 to your computer and use it in GitHub Desktop.
Voting Overview
class Item < ApplicationRecord
has_many :groupings
has_many :lists, through: :groupings
end
class List < ApplicationRecord
has_many :groupings
has_many :items, through: :groupings
end
class Grouping < ApplicationRecord
belongs_to :item
belongs_to :list
has_many :votes
validates :item, :list, presence: true
validate :title_must_be_unique_within_list
def title_must_be_unique_within_list
# Get all the titles of the items in the list
titles = list.items.pluck(:title)
# Add the item title to the array
titles << item.title
# Check if uniq removes any item
# - if it does we add a meaningful error
# - if it does not we have successfully validated the new grouping
unless titles == titles.uniq
errors.add(:item, "list already has an item with this title")
end
end
end
class Vote < ApplicationRecord
belongs_to :grouping, counter_cache: :votes_count
belongs_to :user
validates :grouping, :user, presence: true
end
class User < ApplicationRecord
has_many :votes
end
class NeededMigrations < ActiveRecord::Migration[5.0]
def change
create_table :items do |t|
t.string :name
t.timestamps
end
create_table :list do |t|
t.string :name
t.timestamps
end
create_table :groupings do |t|
t.belongs_to :item, index: true
t.belongs_to :list, index: true
t.integer :votes_count, default: 0
t.timestamps
end
create_table :votes do |t|
t.belongs_to :grouping, index: true
t.belongs_to :user, index: true
t.timestamps
end
create_table :users do |t|
t.string :name
t.timestamps
end
end
Rails.application.routes.draw do
resources :groupings do
resource :votes, only: [:create, :destroy]
end
end
class VotesController < ApplicationController
# This could have json responses.
# You could do buttons for the up and down to request
# create and destroy respectively.
#
# You can even authorize before creating/destroying.
# Or validating if a vote was already cast by that user.
def create
grouping = Grouping.find(params[:grouping_id])
vote = Vote.new(grouping: grouping, user: current_user)
...
end
def destroy
grouping = Grouping.find(params[:grouping_id])
vote = Vote.find(grouping: grouping, user: current_user)
vote.destroy
...
end
end
# Get votes_count for a item in a list
Grouping.first.votes_count
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment