Hello. Made a vote and it became necessary to prohibit a second vote. Decided through user id. To do this, created a table and in it two fields user_id and poll_id. That is, when entering a vote, we look at the table for all the current voting id, take the current user id, and if there are matches, this user already had this vote, then we prohibit him from voting here, if the user id does not match any voting id, then we give him to vote and write to the table id voting and user id. Tell me please, I think correctly? Or piled on garbage? And this table should be connected with user and poll tables?
2 answers
Your decision is correct and adequate. Add a unique composite key to the table (user_id, poll_id), then the database itself will not allow identical entries in the database and, consequently, several votes of one user by one vote. Foreign keys should also be added to the user and poll tables.
Before voting, make a request for this table using a unique composite key and, if there is a record, do not allow voting, you can also write this selected record to the cache so that you do not have to access the table once again.
It is possible, but not necessary, for additional information to add there the date and time when the user voted, the voting statistics will be visible here, and in the future you can add different functionality related to restricting voting by time or number of votes for a certain interval.
- And you can also add how a person voted, so that a person who voted, for example, could cancel his vote / re-vote. - Visman
It seems to work, here is the controller code:
public function actionPoll($id, $user_id, $poll_id) { $single = Poll::getOne($id); $getdata = PollUser::getData($user_id, $poll_id); $u = Yii::$app->user->id; if ($u != $getdata->user_id && $id != $getdata->poll_id) { if ($single->load(Yii::$app->request->post())) { if ($single->count1) { $single->updateCounters(['count1' => 1]); } if ($single->count2) { $single->updateCounters(['count2' => 1]); } if ($single->count3) { $single->updateCounters(['count3' => 1]); } Yii::$app->db->createCommand("INSERT INTO poll_user (user_id, poll_id) VALUES ($u, $id)")->execute(); return $this->redirect("/site/poll/?id=$single->id&user_id=$u&poll_id=$single->id"); } } else { return $this->render('pollonlyresult', ['single' => $single, 'getdata' => $getdata]); } return $this->render('poll', ['single' => $single, 'getdata' => $getdata]); }
Take a vote. We take the data from the check table. We get the login user id - check for matches in the check table - if there are no matches, then we vote and record the current user and vote in the table. Redirect to the results page. If there is a match, then immediately redirect to the page with the results. It seems to be so, many thanks to all who answered.
COUNT
records for the current user and vote, you do not need the records themselves. If zero records - you can vote, if not zero - you can not. Above you almost the same wrote, I support. I just add thatCOUNT
enough for you to use: transfer less data from SQL, spend less RAM. - AK ♦COUNT
is not much better, butLIMIT 1
better :) - Visman