Как проверить, оценил ли пользователь отзыв?

В настоящее время я занимаюсь разработкой системы рецензирования книг с использованием 5-звездочного рейтинга. Я хочу добавить рейтинговую систему к каждому обзору поста пользователя. поэтому я создал таблицу для хранения каждой ставки и bookId, который был оценен в настоящее время, а также id, рецензии и userId, которые опубликовали следующее:

id  Review  rating  AppUser_id  Book_id
46  reviw1  2           6          23
53  reviw2  3           6         23 

Ниже приведены HTML для звезд:

    {% if UserId >0 %}
    <form class="form-signin" action="/BookReview{% if ReviewId != -1 %}/{{ ReviewId }}{% endif %}/{{ act }}" method="POST">

        <h2 class="form-signin-heading">Please Post Your Review</h2>
        <label for="Review" class="sr-only">Review</label>

        <textarea name="review" id="Review" class="form-control" placeholder="Your Review Here" required autofocus>{{ review }}</textarea>

        <button class="btn btn-lg btn-primary btn-block" type="submit" >Submit</button>
        <fieldset class="rating">
            <input type="radio" id="star5" name="rating5" value="5" /><label for="star5" title="Rocks!">5 stars</label>
            <input type="radio" id="star4" name="rating4" value="4" /><label for="star4" title="Pretty good">4 stars</label>
            <input type="radio" id="star3" name="rating3" value="3" /><label for="star3" title="Meh">3 stars</label>
            <input type="radio" id="star2" name="rating2" value="2" /><label for="star2" title="Kinda bad">2 stars</label>
            <input type="radio" id="star1" name="rating1" value="1" /><label for="star1" title="Sucks big time">1 star</label>
        </fieldset>
    </form>
    {% endif %}

следующий контроллер:

    if ($request->getMethod() == 'POST' and $act == -1) {
        $em = $this->getDoctrine()->getManager();
        $review = $request->request->get('review');
        $review = $request->request->get('BookId');
        $rate1 = $request->request->get('rating1');
        $rate2 = $request->request->get('rating2');
        $rate3 = $request->request->get('rating3');
        $rate4 = $request->request->get('rating4');
        $rate5 = $request->request->get('rating5');


        $br = new BookReview();
        $br->setReview($review);
        $repository = $this->getDoctrine()->getRepository('AppBundle:AppUser');
        $User = $repository->findOneBy(array('id' => $userId));
        $br->setAppUser($User);
        $br->setBook($book);


            if($rate1)
            {
                $br->setRating(1);

            }elseif($rate2)
            {
                $br->setRating(2);
            }elseif($rate3)
            {
                $br->setRating(3);
            }elseif($rate4)
            {
                $br->setRating(4);
            }elseif($rate5)
            {
                $br->setRating(5);
            }


        $em->persist($br);
        $em->flush();
        $request->getSession()->getFlashBag()->add('success', 'Review Added');

        return array('book' => $book, 'reviews' => $book->getBookReviews(), 'Title' => '', 'Message' => '', 'id' => $userId, 'review' => '', 'ReviewId' => $ReviewId, 'act' => $act);
    }

вот мой вопрос, как я могу проверить, оценивал ли пользователь ту же книгу раньше и оценивал ли он книгу раньше, а затем установить скорость, используя эту часть кода, которая полностью указана на вышеуказанном контроллере:

if($rate1)
                {
                    $br->setRating(1);

                }elseif($rate2)
                {
                    $br->setRating(2);
                }elseif($rate3)
                {
                    $br->setRating(3);
                }elseif($rate4)
                {
                    $br->setRating(4);
                }elseif($rate5)
                {
                    $br->setRating(5);
                }

Второй вопрос заключается в том, как рассчитать общий средний рейтинг книги. Я использую symfony2(PHP)

Вот моя попытка, которая, кажется, не работает:

        $br = new BookReview();

        $br->setReview($review);
        $repository = $this->getDoctrine()->getRepository('AppBundle:AppUser');
        $User = $repository->findOneBy(array('id' => $userId));
        $br->setAppUser($User);
        $br->setBook($book);
        $book_id = $br->getBook(); $request->request->get('book_id');
        $user_id = $br->getAppUser(); $request->request->get('user_id');
        $query = $em->createQuery('SELECT br FROM AppBundle:BookReview br WHERE (br.Book = ' . $book_id . ' and br.AppUser = ' . $user_id . ')');

        $results = $query->getResult();



        if ($results){
            $request->getSession()->getFlashBag()->add('success', 'no Added');

        }


        else{

            if($rate1)
            {
                $br->setRating(1);

            }elseif($rate2)
            {
                $br->setRating(2);
            }elseif($rate3)
            {
                $br->setRating(3);
            }elseif($rate4)
            {
                $br->setRating(4);
            }elseif($rate5)
            {
                $br->setRating(5);
            }
        }

3 ответа

Прежде всего, ваш контроллер и вид выглядят немного грязно. Зачем вам нужны разные имена для рейтинговых полей? Это не радио кнопки. Просто установите одинаковое имя для всех ваших радио кнопок. Тогда вам не понадобится условие if-else, чтобы определить, какое значение рейтинга было выбрано.

Чтобы узнать, просматривал ли пользователь какую-либо книгу, вам нужно знать, есть ли запись с таким user_id и таким book_id. Это извлечение не требует возврата объекта в результате, и намного проще выполнить простой sql, чтобы получить количество строк с соответствующими значениями. Вы можете сделать это с помощью сервиса database_connection с вашего контроллера:

$this->get('database_connection')
     ->fetchColumn('select count(*) as cnt 
                    from book_reviews 
                    where user_id = ? and book_id = ?', array($userId, $bookId));

Или из хранилища:

public function userHasAlreadyReviewedBook($userId, $bookId)
{
    $connection = $this->getEntityManager()->getConnection();
    $query = 'select count(*) as cnt 
              from book_reviews 
              where user_id = ? and book_id = ?';

    return $connection->fetchColumn($query, array($userId, $bookId)) > 0;
}

Или вы можете указать специальный сервис для таких действий и вставить 'database_connection' в него.

Если запрос выше вернет что-то больше нуля, то пользователь уже просмотрел книгу.

Чтобы получить среднее значение рейтинга рецензий на книги, вы снова можете использовать сервис database_connection (конечно, если вам не нужно указывать это значение в каком-то сложном наборе данных):

Для каждой книги в обзорах:

$connection->fetchAll('select avg(rating) as average_rating 
                       from book_reviews 
                       group by book_id');

или для какой-то специальной книги:

$connection->fetchColumn('select avg(rating) as average_rating 
                          from book_reviews 
                          where book_id = ?', array($bookId));

Надеюсь, это поможет.

Сначала я настоятельно рекомендую вам дать всем вашим радиовходам имя rating (не rating1, rating2...) Таким образом, вы будете знать, какой рейтинг пользователь дал книге, получив значение $request->request->get('rating'),

Теперь, как проверить, оценил ли пользователь эту книгу? Используйте этот запрос:

$repository = $this->getDoctrine()->getRepository('AppBundle:BookReview');
$bookReview = $repository->findOneBy(array('AppUser_id' => $userId, 'Book_id' => $bookId));

if (!$bookReview) {
    $bookReview = new BookReview();
    $bookReview->setUser($user);
    $bookReview->setBook($book);
    $this->getDoctrine()->getManager()->persist();
}

$bookReview->setRating($request->request->get('rating'));

$this->getDoctrine()->getManager()->flush();

В вашем хранилище вы можете добавить это:

public function getCurrentRated($bookId, $userId)
{
$sql = 'SELECT avg(rating) as totalRated FROM your_table WHERE AppUser_id = :userId and Book_id = :bookId group by Book_id';
$params = array(
    'userId' => $userId,
    'bookId' => $bookId,
);

return $this->getEntityManager()->getConnection()->executeQuery($sql, $params)->fetchAll();
}

А затем вызовите его в вашем контроллере следующим образом:

$currentRated = $repository->getCurrentRated($bookId, $userId);
Другие вопросы по тегам