Простая система голосования без жемчужин - как отследить или понизить голосование и позволить один голос за user_id - PullRequest
1 голос
/ 28 апреля 2020

Любая помощь будет наиболее ценной. Я меньше трех недель в своем путешествии, поэтому заранее извиняюсь.

Я написал простую систему голосования по спискам, пользователь может голосовать за или против указанного списка. Это работает хорошо. Тем не менее, я застрял в двух вопросах:

  1. Какой самый эффективный способ ограничения user_id голосовать один раз? Тем не менее, они могут переключить свой голос вверх или вниз. Я начал сверхинжиниринг after_touch Callback. Является ли лучшая практика для установки has_one: голоса в модели пользователя? После этого Active Record позаботится обо всем?
  2. Можно ли отключить кнопку голосования (вверх или вниз), когда пользователь нажимает кнопку. Без добавления еще одного столбца базы данных для отслеживания голосов "за" или "против" Таким образом, они могут переключаться между голосованием вверх или вниз после первоначального голосования.

Контролер голосов

class VotesController < ApplicationController
    def vote_up
        @list = List.find(params[:list_id])
        @vote = Vote.find_or_create_by(list_id: params[:id], user_id: current_user.id)
        Vote.increment_counter(:vote_count, @vote)
        redirect_to list_path(@list), notice: 'Voted Up.'
    end

    def vote_down
        @list = List.find(params[:list_id])
        @vote = Vote.find_or_create_by(list_id: params[:id], user_id: current_user.id)
        Vote.decrement_counter(:vote_count, @vote)
        redirect_to list_path(@list), notice: 'Voted Down.'    
    end
end

схема

  create_table "votes", force: :cascade do |t|
    t.integer "vote_count"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.bigint "list_id", null: false
    t.integer "user_id"
    t.index ["list_id"], name: "index_votes_on_list_id"
  end

отрывок из шоу. html .erb с соответствующими кнопками голосования вверх / вниз

<% if @list.votes.any? %>
  Count Of Votes <%= content_tag(:p, list_vote_counter?) %>
<% end %>
<%= button_to 'Vote Up', list_vote_up_path, method: :post, params: { list_id: params[:id] } %>
<%= button_to 'Vote Down', list_vote_down_path, method: :post, params: { list_id: params[:id] } %>

Заранее спасибо.

1 Ответ

0 голосов
/ 28 апреля 2020

Это сбивает с толку. Вы говорите, что хотите установить User на has_one :vote. Но ваш стол выглядит как стол соединения для user_id и list_id. Таким образом, человек может иметь ОДИН голос за СПИСОК, верно? Вы можете обеспечить уникальность, но не так, как вы упомянули.

У вас нет кода модели для всех моделей, но вы можете сделать модель списка имеющей

has_many :votes
has_many :users, through: :votes

Тогда у пользователей есть

has_many :votes
has_many :lists, through: votes

и модель Votes может иметь

belongs_to: :user
belongs_to: :list
validates :user_id, :uniqueness => { :scope => :list_id }

Эта последняя проверка уникальности будет препятствовать более чем одному голосованию пользователя в списке из того, что я понимаю здесь: http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#method -i-validates_uniqueness_of

...