使用 Symfony 3 访问多对一关系的用户分数
Access User Scores on Many-to-One Relationship using Symfony 3
我正在创建一个应用程序,根据用户解决的问题将用户分数保存在数据库中。我有用户、问题和提交实体。对于所有这些,我都与用户实体建立了一对多关系。问题实体具有保存问题分数的点域。我正在尝试检索所有用户的总分。
这是我的控制器;
$userService = $this->container->get('userservice');
$users = $userService->findAll();
foreach ($users as $user){
$usersWPoints = $user->getSubmissions()->getProblemId()->getPoints;
}
然而这个returns出现以下错误;
Attempted to call an undefined method named "getProblemId" of class "Doctrine\ORM\PersistentCollection".
这是我的模型
User.php
/**
* Class User
* @package AppBundle\Entity
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @ORM\Table(name="user")
* @ORM\HasLifecycleCallbacks()
* @UniqueEntity(fields="username", message="Email already taken")
*
*/
class User implements UserInterface
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please enter a valid email address")
* @Assert\Email()
*/
private $username;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please enter a valid email address")
*/
private $usrname;
/**
* @Assert\NotBlank()
* @Assert\Length(max=4096)
*/
private $plainPassword;
/**
* The below length depends on the "algorithm" you use for encoding
* the password, but this works well with bcrypt.
*
* @ORM\Column(type="string", length=64)
*/
private $password;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please enter a valid name")
*/
private $fullname;
/**
* @var array
* @ORM\Column(name="roles", type="json_array")
*/
protected $roles;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Problem", mappedBy="createdby")
*/
protected $problems;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Feed", mappedBy="createdby")
*/
protected $feeds;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Comment", mappedBy="createdby")
*/
protected $comments;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Submission", mappedBy="user_id")
*/
protected $submissions;
// other properties and methods
public function getUsername()
{
return $this->username;
}
public function setUsername($username)
{
$this->username = $username;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function setPlainPassword($password)
{
$this->plainPassword = $password;
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password)
{
$this->password = $password;
}
public function getSalt()
{
// The bcrypt algorithm doesn't require a separate salt.
// You *may* need a real salt if you choose a different encoder.
return null;
}
// other methods, including security methods like getRoles()
/**
* @return array
*/
public function getRoles()
{
return $this->roles;
}
public function setRoles(array $roles){
$this->roles = $roles;
return $this;
}
/**
* @return mixed
*/
public function getFullname()
{
return $this->fullname;
}
/**
* @param mixed $fullname
*/
public function setFullname($fullname)
{
$this->fullname = $fullname;
}
/**
* @return mixed
*/
public function getUsrname()
{
return $this->usrname;
}
/**
* @param mixed $usrname
*/
public function setUsrname($usrname)
{
$this->usrname = $usrname;
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return \Doctrine\Common\Collections\Collection
*/
public function getSubmissions()
{
return $this->submissions;
}
Problem.php
/**
* Class Problem
* @package AppBundle\Entity
* @ORM\Entity(repositoryClass="AppBundle\Repository\ProblemRepository")
* @ORM\Table(name="problem")
* @ORM\HasLifecycleCallbacks()
*
*/
class Problem
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, unique=True)
* @Assert\NotBlank(message="Please enter a valid title")
*/
protected $title;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Please enter a valid description")
*/
protected $description;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Please enter a valid value")
*/
protected $points;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Please enter a valid flag")
*/
protected $flag;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Please enter a valid value")
*/
protected $category;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="problems")
* @ORM\JoinColumn(name="createdby", referencedColumnName="id")
*/
protected $createdby;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Submission", mappedBy="problem_id")
*/
protected $submissions;
/**
* @Gedmo\Slug(fields={"title"})
* @ORM\Column(type="string", length=255, unique=false,)
*/
protected $slug;
/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* @param mixed $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return mixed
*/
public function getDescription()
{
return $this->description;
}
/**
* @param mixed $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @return mixed
*/
public function getPoints()
{
return $this->points;
}
/**
* @param mixed $points
*/
public function setPoints($points)
{
$this->points = $points;
}
/**
* @return mixed
*/
public function getFlag()
{
return $this->flag;
}
/**
* @param mixed $flag
*/
public function setFlag($flag)
{
$this->flag = $flag;
}
/**
* @return mixed
*/
public function getCategory()
{
return $this->category;
}
/**
* @param mixed $category
*/
public function setCategory($category)
{
$this->category = $category;
}
/**
* @return mixed
*/
public function getCreatedby()
{
return $this->createdby;
}
/**
* @param mixed $createdby
*/
public function setCreatedby($createdby)
{
$this->createdby = $createdby;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set slug
*
* @param string $slug
*
* @return Problem
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* @return mixed
*/
public function getSubmissions()
{
return $this->submissions;
}
/**
* @param mixed $submissions
*/
public function setSubmissions($submissions)
{
$this->submissions = $submissions;
}
}
Submission.php
class Submission
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Problem", inversedBy="submissions")
* @ORM\JoinColumn(name="problem_id", referencedColumnName="id")
*/
protected $problem_id;
/**
* @ORM\Column(type="boolean")
*/
protected $correct = false;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="submissions")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user_id;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Flag cannot be blank")
*/
protected $submission_flag;
/**
* @return mixed
*/
public function getProblemId()
{
return $this->problem_id;
}
/**
* @param mixed $problem_id
*/
public function setProblemId($problem_id)
{
$this->problem_id = $problem_id;
}
/**
* @return mixed
*/
public function getCorrect()
{
return $this->correct;
}
/**
* @param mixed $correct
*/
public function setCorrect($correct)
{
$this->correct = $correct;
}
/**
* @return mixed
*/
public function getUserId()
{
return $this->user_id;
}
/**
* @param mixed $user_id
*/
public function setUserId($user_id)
{
$this->user_id = $user_id;
}
/**
* @return mixed
*/
public function getSubmissionFlag()
{
return $this->submission_flag;
}
/**
* @param mixed $submission_flag
*/
public function setSubmissionFlag($submission_flag)
{
$this->submission_flag = $submission_flag;
}
}
如有任何关于访问每个用户及其总分的建议,我们将不胜感激。
getSubmissions() returns 集合和 getProblemId() 是提交的方法。
因此,一旦每个用户都有很多提交 - 我会为用户创建一些 getTotalPoints() 方法,您可以在其中 运行 在 foreach 中。
这种方式:
public function getTotalPoints()
{
$submissions = $this->getSubmissions();
$points = 0;
foreach ($submissions as $submission) {
$points += $submission->getProblemId()->getPoints();
}
return $points;
}
你可以这样做:
$userService = $this->container->get('userservice');
$users = $userService->findAll();
$pointPerUser = array();
foreach ($users as $user){
$userSubmissions = $user->getSubmissions();
$pointPerUser[$user->getId()] = 0;
foreach ($userSubmissions as $userSubmission) {
// Probably here you want to check if the submission is correct
$pointPerUser[$user->getId()] += $userSubmission->getProblemId()->getPoints();
}
}
顺便说一句,提交属性不应该是$problem_id而是$problem,方法是getProblem(),因为你得到的是一个Problem实例,而不是一个id。 table 的字段名称是可以的,因为您正在存储一个 id。
我正在创建一个应用程序,根据用户解决的问题将用户分数保存在数据库中。我有用户、问题和提交实体。对于所有这些,我都与用户实体建立了一对多关系。问题实体具有保存问题分数的点域。我正在尝试检索所有用户的总分。
这是我的控制器;
$userService = $this->container->get('userservice');
$users = $userService->findAll();
foreach ($users as $user){
$usersWPoints = $user->getSubmissions()->getProblemId()->getPoints;
}
然而这个returns出现以下错误;
Attempted to call an undefined method named "getProblemId" of class "Doctrine\ORM\PersistentCollection".
这是我的模型
User.php
/**
* Class User
* @package AppBundle\Entity
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @ORM\Table(name="user")
* @ORM\HasLifecycleCallbacks()
* @UniqueEntity(fields="username", message="Email already taken")
*
*/
class User implements UserInterface
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please enter a valid email address")
* @Assert\Email()
*/
private $username;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please enter a valid email address")
*/
private $usrname;
/**
* @Assert\NotBlank()
* @Assert\Length(max=4096)
*/
private $plainPassword;
/**
* The below length depends on the "algorithm" you use for encoding
* the password, but this works well with bcrypt.
*
* @ORM\Column(type="string", length=64)
*/
private $password;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please enter a valid name")
*/
private $fullname;
/**
* @var array
* @ORM\Column(name="roles", type="json_array")
*/
protected $roles;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Problem", mappedBy="createdby")
*/
protected $problems;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Feed", mappedBy="createdby")
*/
protected $feeds;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Comment", mappedBy="createdby")
*/
protected $comments;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Submission", mappedBy="user_id")
*/
protected $submissions;
// other properties and methods
public function getUsername()
{
return $this->username;
}
public function setUsername($username)
{
$this->username = $username;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function setPlainPassword($password)
{
$this->plainPassword = $password;
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password)
{
$this->password = $password;
}
public function getSalt()
{
// The bcrypt algorithm doesn't require a separate salt.
// You *may* need a real salt if you choose a different encoder.
return null;
}
// other methods, including security methods like getRoles()
/**
* @return array
*/
public function getRoles()
{
return $this->roles;
}
public function setRoles(array $roles){
$this->roles = $roles;
return $this;
}
/**
* @return mixed
*/
public function getFullname()
{
return $this->fullname;
}
/**
* @param mixed $fullname
*/
public function setFullname($fullname)
{
$this->fullname = $fullname;
}
/**
* @return mixed
*/
public function getUsrname()
{
return $this->usrname;
}
/**
* @param mixed $usrname
*/
public function setUsrname($usrname)
{
$this->usrname = $usrname;
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return \Doctrine\Common\Collections\Collection
*/
public function getSubmissions()
{
return $this->submissions;
}
Problem.php
/**
* Class Problem
* @package AppBundle\Entity
* @ORM\Entity(repositoryClass="AppBundle\Repository\ProblemRepository")
* @ORM\Table(name="problem")
* @ORM\HasLifecycleCallbacks()
*
*/
class Problem
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, unique=True)
* @Assert\NotBlank(message="Please enter a valid title")
*/
protected $title;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Please enter a valid description")
*/
protected $description;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Please enter a valid value")
*/
protected $points;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Please enter a valid flag")
*/
protected $flag;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Please enter a valid value")
*/
protected $category;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="problems")
* @ORM\JoinColumn(name="createdby", referencedColumnName="id")
*/
protected $createdby;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Submission", mappedBy="problem_id")
*/
protected $submissions;
/**
* @Gedmo\Slug(fields={"title"})
* @ORM\Column(type="string", length=255, unique=false,)
*/
protected $slug;
/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* @param mixed $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return mixed
*/
public function getDescription()
{
return $this->description;
}
/**
* @param mixed $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @return mixed
*/
public function getPoints()
{
return $this->points;
}
/**
* @param mixed $points
*/
public function setPoints($points)
{
$this->points = $points;
}
/**
* @return mixed
*/
public function getFlag()
{
return $this->flag;
}
/**
* @param mixed $flag
*/
public function setFlag($flag)
{
$this->flag = $flag;
}
/**
* @return mixed
*/
public function getCategory()
{
return $this->category;
}
/**
* @param mixed $category
*/
public function setCategory($category)
{
$this->category = $category;
}
/**
* @return mixed
*/
public function getCreatedby()
{
return $this->createdby;
}
/**
* @param mixed $createdby
*/
public function setCreatedby($createdby)
{
$this->createdby = $createdby;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set slug
*
* @param string $slug
*
* @return Problem
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* @return mixed
*/
public function getSubmissions()
{
return $this->submissions;
}
/**
* @param mixed $submissions
*/
public function setSubmissions($submissions)
{
$this->submissions = $submissions;
}
}
Submission.php
class Submission
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Problem", inversedBy="submissions")
* @ORM\JoinColumn(name="problem_id", referencedColumnName="id")
*/
protected $problem_id;
/**
* @ORM\Column(type="boolean")
*/
protected $correct = false;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="submissions")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user_id;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="Flag cannot be blank")
*/
protected $submission_flag;
/**
* @return mixed
*/
public function getProblemId()
{
return $this->problem_id;
}
/**
* @param mixed $problem_id
*/
public function setProblemId($problem_id)
{
$this->problem_id = $problem_id;
}
/**
* @return mixed
*/
public function getCorrect()
{
return $this->correct;
}
/**
* @param mixed $correct
*/
public function setCorrect($correct)
{
$this->correct = $correct;
}
/**
* @return mixed
*/
public function getUserId()
{
return $this->user_id;
}
/**
* @param mixed $user_id
*/
public function setUserId($user_id)
{
$this->user_id = $user_id;
}
/**
* @return mixed
*/
public function getSubmissionFlag()
{
return $this->submission_flag;
}
/**
* @param mixed $submission_flag
*/
public function setSubmissionFlag($submission_flag)
{
$this->submission_flag = $submission_flag;
}
}
如有任何关于访问每个用户及其总分的建议,我们将不胜感激。
getSubmissions() returns 集合和 getProblemId() 是提交的方法。 因此,一旦每个用户都有很多提交 - 我会为用户创建一些 getTotalPoints() 方法,您可以在其中 运行 在 foreach 中。 这种方式:
public function getTotalPoints()
{
$submissions = $this->getSubmissions();
$points = 0;
foreach ($submissions as $submission) {
$points += $submission->getProblemId()->getPoints();
}
return $points;
}
你可以这样做:
$userService = $this->container->get('userservice');
$users = $userService->findAll();
$pointPerUser = array();
foreach ($users as $user){
$userSubmissions = $user->getSubmissions();
$pointPerUser[$user->getId()] = 0;
foreach ($userSubmissions as $userSubmission) {
// Probably here you want to check if the submission is correct
$pointPerUser[$user->getId()] += $userSubmission->getProblemId()->getPoints();
}
}
顺便说一句,提交属性不应该是$problem_id而是$problem,方法是getProblem(),因为你得到的是一个Problem实例,而不是一个id。 table 的字段名称是可以的,因为您正在存储一个 id。