Doctrine Associations in symfony - php

so I have been working with Symfony for a while but there is one thing that bothers.
It's about Doctrine Associations.
The thing is that I am trying to achieve a user friend invites and relations and there is a page that the user can see the invitations he sent and the ones that are pending.
EDIT: I made it happen using Many-To-One/One-To-Many associations. However
My question is - Are Doctrine Associations the correct way of doing that.
My User Entity
class User implements UserInterface
{
private $id;
/**
* #ORM\Column(name="first_name", type="string", length=30)
*
* #Assert\NotBlank(message="First name cannot be a blank field", groups={"register"})
* #Assert\Length(min="3", max="30", groups={"register"})
*/
/**
* #ORM\Column(type="string", length=50)
*
* #Assert\NotBlank(message="Username cannot be a blank field", groups={"register"})
* #Assert\Length(min="7", max="50", groups={"register"})
*/
private $username;
/**
* #ORM\Column(type="string", length=255)
*
* #Assert\Length(min="7", max="50", groups={"register"})
*/
private $password;
/**
* #ORM\OneToMany(targetEntity="App\Entity\UserInvitation", mappedBy="inviterId", orphanRemoval=true)
*/
private $userInvitations;
/**
* #ORM\OneToMany(targetEntity="App\Entity\UserInvitation", mappedBy="invitedId", orphanRemoval=true)
*/
private $pendingUserInvitations;
//getters and setters
My UserInvitation Entity
class UserInvitation
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="userInvitations")
* #ORM\JoinColumn(name="inviter_id", nullable=false)
*/
private $inviterId;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="pendingUserInvitations")
* #ORM\JoinColumn(name="invited_id", nullable=false)
*/
private $invitedId;
/**
* #ORM\Column(type="boolean")
*/
private $status;
This is my database.

The relationships is the right way to do it although on the entity I would use the following:
class UserInvitation
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="userInvitations")
* #ORM\JoinColumn(name="inviter_id", nullable=false)
*/
private $inviter;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="pendingUserInvitations")
* #ORM\JoinColumn(name="invited_id", nullable=false)
*/
private $invitee;
/**
* #ORM\Column(type="boolean")
*/
private $status;
Then you would getInviter() or setInviter(). Basically think that you are saving the related object to the entity and not the related field

Related

Doctrine ManyToOne relation with compositeKey

I have 2 entities let's say company and address they are related like this:
class Company
{
/**
* #ORM\Id()
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\Column(type="string", length=20, name="company_id")
* #Groups({"read", "write"})
*/
private $id;
/**
* #ORM\Column(type="string", length=20, name="group_id")
* #Groups({"read", "write"})
*/
private $groupId;
/**
* #ORM\ManyToOne(targetEntity=Address::class, inversedBy="company")
* #ORM\JoinColumns(
* {
* #ORM\JoinColumn(nullable=true, referencedColumnName="address_id", name="address_id"),
* #ORM\JoinColumn(nullable=true, referencedColumnName="group_id", name="group_id")
*
* })
* #Groups({"read", "write"})
*/
private $address;
class Address
{
/**
* #ORM\Id()
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\Column(type="string", length=20, name="address_id")
* #Groups({"read", "write"})
*/
private $id;
/**
* #ORM\Id()
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\Column(type="integer", name="group_id")
*/
private $groupId;
the problem I'm encountering is when I don't provide something for relation in Company::$address I'll get group_id = null even when I try to set it in various ways.
I found the line which is responsible for setting it to null vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:704
For now, I resolved it by adding a second column, company_group_id, but I was wondering if there is a better way to do this

#ORM\ManyToOne (Doctrine trying to fill object instead of int value into column)

I'm working on a form using a #ORM\ManyToOne association, but Doctrine keeps trying to parse the Airport Entity instead of the id of the Airport Entity, I've tried several annotations like #ORM\JoinColumn(name="id", referencedColumnName="id") but I can't find the right annotation to make doctrine parse just the id of the entity instead of the entity object, any help would be appreciated. Also I'm not seeking a quick and dirty fix, I'm seeking a clean and correct way to do this using the Doctrine annotations if possible.
Full Error Message:
An exception occurred while executing 'INSERT INTO flight (from, to) VALUES (?, ?)' with params [{}, {}]:
Notice: Object of class App\Entity\Airport could not be converted to int
Flight.php
/**
* #ORM\Entity(repositoryClass="App\Repository\FlightRepository")
* #ORM\Table(name="flight",
* uniqueConstraints={#ORM\UniqueConstraint(name="flight",columns={"from","to"})}
* )
*/
class Flight
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Airport", inversedBy="outbound")
* #ORM\JoinColumn(name="id")
*/
private $from;
/**
* #ORM\ManyToOne(targetEntity="Airport", inversedBy="inbound")
* #ORM\JoinColumn(name="id")
*/
private $to;
public function __toString()
{
return $this->name;
}
Airport.php
/**
* #ORM\Entity(repositoryClass="App\Repository\AirportRepository")
*/
class Airport
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="string", length=200)
*/
private $region;
/**
* #ORM\OneToMany(targetEntity="Flight", mappedBy="to")
*/
private $inbound;
/**
* #ORM\OneToMany(targetEntity="Flight", mappedBy="from")
*/
private $outbound;
I finally figured out that the issue was on the #ORM\ManyToOne() side, by chatting with Jakumi:
And that #ORM\JoinColumn() converts the entity to a int.
He also pointed out from is a reserved keyword in MySQL so I changed the column name to ap_from.
Flight.php
/**
* #ORM\Entity(repositoryClass="App\Repository\FlightRepository")
* #ORM\Table(name="flight",
* uniqueConstraints={#ORM\UniqueConstraint(name="flight",columns={"ap_from","ap_to"})}
* )
*/
class Flight
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Airport", inversedBy="outbound")
* #ORM\JoinColumn(name="ap_from", referencedColumnName="id")
*/
private $from;
/**
* #ORM\ManyToOne(targetEntity="Airport", inversedBy="inbound")
* #ORM\JoinColumn(name="ap_to", referencedColumnName="id")
*/
private $to;
/**
* #ORM\Column(type="text")
*/
private $kfm;
i don't see any use of putting the oneToMany annotation in the airport class or even the attributes inbounf and outbound just keep the from and to in your flight class then you access to any attribute in the airport throw your flight entity
your code should look like that :
Flight.php:
class Flight{/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Airport")
* #ORM\JoinColumn(name="airportFrom" , referencedColumnName="id")
*/
private $from;
/**
* #ORM\ManyToOne(targetEntity="Airport")
* #ORM\JoinColumn(name="airportTo", referencedCol)
*/
private $to;
Airport.php
class Airport{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="string", length=200)
*/
private $region;
and if you are worried about how to get the flights coming in or out from an airport a simple sql query should do it

Symfony ManyToOne Form add, delete in DB

I have entity developer and comment and relationship Many comment to One developer. And I need form when I see all comment for developer and edit - add, delete in DB . What are the solutions to this problem
entity Comment:
class Comments
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Developer", inversedBy="comments")
* #ORM\JoinColumn(name="talent_id", nullable = true, referencedColumnName="id")
* */
protected $talent;
/**
* #var string
*
* #ORM\Column(name="added_by", type="string", length=10, nullable=true)
*/
private $added_by;
/**
* #var string
*
* #ORM\Column(name="comment", type="string", length=10, nullable=true)
*/
private $comment;
entity Developer:
class Developer extends CustomUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/////
/**
* #ORM\OneToMany(targetEntity="Comments", mappedBy="talent", cascade={"persist", "remove"})
*/
protected $comments;
Maybe need form in form but how to do this?
You are looking for field type collection.
Example usage of collection type
class Comments
{
....
/**
*
*#ORM\ManyToOne(targetEntity="Developer", inversedBy="developer_to_comments")
* #ORM\JoinColumn(name="developer_to_comments_id", referencedColumnName="id", nullable=false)
*
*/
private $comments_to_developer;
...
}
And class Developer
class Developer extends CustomUser
{
....
/**
*
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="Comments", mappedBy="comments_to_developer", cascade={"remove"})
*/
private $developer_to_comments;
public function __construct()
{
$this->developer_to_comments = new ArrayCollection();
}
....
}
And don't forget use Doctrine\Common\Collections\ArrayCollection

Doctrine - ManyToOne with table between

I want to create model which will have table users with reference to table CustomFieldValue nad table CustomField with reference to CustomFieldValue too. CustomFieldValue will have only id, value and two columns, one from users and second from CustomField. I want to have functionality like a dynamic adding a new fields in registration form. Is this good idea? If yes, please help me with this model, because it doesn't work:
User:
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* #ORM\Column(type="string", length=64)
*/
private $password;
/**
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users",cascade={"persist"})
*
*/
private $roles;
/**
* #ORM\Column(type="string", length=60, unique=true)
*/
private $email;
/**
* #ORM\Column(type="string", length=60)
*/
private $sex;
/**
* #ORM\ManyToMany(targetEntity="Region", inversedBy="users")
* #ORM\JoinColumn(name="region", referencedColumnName="id")
*/
private $region;
/**
* #ORM\ManyToMany(targetEntity="Type", inversedBy="users")
* #ORM\JoinColumn(name="type", referencedColumnName="id")
*/
private $type;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* #ORM\ManyToOne(targetEntity="CustomFieldValue",inversedBy="id")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $customValues;
CustomFieldValue:
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="value", type="string", length=255)
*/
private $value;
/**
*ORM\OneToMany(targetEntity="User", mapped-by="id")
*#ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
*#ORM\OneToMany(targetEntity="CustomField", mapped-by="id" )
*#ORM\JoinColumn(name="field_id", referencedColumnName="id")
*/
private $field;
CustomField:
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=255)
*/
private $type;
/**
* #var boolean
*
* #ORM\Column(name="required", type="boolean")
*/
private $required;
/**
* #ORM\ManyToOne(targetEntity="CustomFieldValue", inversedBy="id")
* #ORM\JoinColumn(name="customfield_id", referencedColumnName="id")
*/
private $customValues;
Your mapping is a little off:
User Entity Should Be:
/**
* #ORM\ManyToOne(targetEntity="CustomFieldValue", inversedBy="user")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $customValues;
CustomFieldValue Should Be:
/**
*ORM\OneToMany(targetEntity="User", mappedBy="customValues")
*/
private $user;
/**
*#ORM\OneToMany(targetEntity="CustomField", mappedBy="customValues" )
*/
private $field;
CustomField should be:
/**
* #ORM\ManyToOne(targetEntity="CustomFieldValue", inversedBy="field")
* #ORM\JoinColumn(name="customfield_id", referencedColumnName="id")
*/
private $customValues;
You dont need the join columns when you are calling the mappedBy this already tells doctrine to look for the join column declaration on that field. For the mappedBy and inversedBy fields these are the fields that link the 2 together NOT the actual join column name.

sonata admin use two entities in an admin

im new to sonata admin, is this possible to use two entities in one admin class?
my User entity,
App\MyBundle\Entity\Users.php
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=45, nullable=true)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=100, nullable=true)
*/
private $email;
my UserProject entity,
App\MyBundle\Entity\UserProjects.php
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var \User
*
* #ORM\ManyToOne(targetEntity="Users")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="userId", referencedColumnName="id")
* })
*/
private $userid;
/**
* #var array
*
* #ORM\Column(name="projectId", type="array")
*/
private $projects;
my Admin class,
class UserAdmin extends SonataUserAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General') // these fields from Users Entity
->add('username')
->add('email')
->with('Projects') // these fields from UserPrjects Entity
/* here i need to add a field for projects related to current user */
}
}
is there any way to get these two entities connect together?
I suggest you to add a One-To-Many in the User side:
/**
* #ORM\OneToMany(targetEntity="UserProjects", mappedBy="userid")
*/
protected $userProjects;
The you can use the UserProjects entity.

Categories