Can`t think of better way to model the database - php

I am trying to create a demo project where there are 3 tables: category, model, type.
There may be different categories, such as cellphone, tablets, computer, etc. For each category there are different types, such as for cellphone there could be asus, iphone, nokia, etc. Likewise, for each type there are different models: for nokia there might be nokia, lumia, nokia n97, etc. How do I create this database in symfony2 using annotations?

The code is not that complicated:
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
*/
class Category
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="Model", mappedBy="category")
*/
private $models;
}
/**
* #ORM\Entity()
*/
class Model
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ManyToOne(targetEntity="Category", inversedBy="models")
* #JoinColumn(name="category_id", referencedColumnName="id")
**/
private $category;
/**
* #ORM\OneToMany(targetEntity="Type", mappedBy="model")
*/
private $types;
}
/**
* #ORM\Entity()
*/
class Type
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="type", type="string", length=255)
*/
private $name;
/**
* #ManyToOne(targetEntity="Model", inversedBy="types")
* #JoinColumn(name="model_id", referencedColumnName="id")
**/
private $model;
}
After adding your code each one in it's file run the command:
php app/console doctrine:generate:entities
and it will generate setters and getters and constructors

Related

Doctrine Associations in symfony

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

symfony2 combine primary key and relation

I'm trying to get a legacy database into the doctrine mappings.
All the tables have a combined primary key. One ID and one "optios id".
The problem is that Optios ID always has to be set but the OneToOne relation with the same columns causes the column "Optios ID" to be set to null. I'm not sure what I'm doing wrong or is there a way around it?
PS: The 'Pack' relation is optional.
<?php
namespace CalendarBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="CalendarBundle\Repository\CategoryRepository")
* #ORM\Table(name="Categories")
*/
class Category
{
/**
* #ORM\Id
* #ORM\Column(type="integer", name="Category_id")
*/
private $id;
/**
* #ORM\Column(type="integer", name="Optios_id")
* #ORM\Id
*/
private $optiosId;
/**
* #ORM\Column(type="string", name="Name")
*/
private $name;
/**
* #ORM\Column(type="boolean", name="AvailableOnline")
*/
private $online;
/**
* #ORM\Column(type="integer", name="SequenceNumber", nullable=true)
*/
private $order;
/**
* #ORM\Column(type="integer", name="Parent_id")
*/
private $parentId;
/**
* One Category has Many Packs.
*
* #var Pack
*
* #ORM\OneToOne(targetEntity="Pack", inversedBy="category")
* #ORM\JoinColumns(
* #ORM\JoinColumn(name="Pack_id", referencedColumnName="Pack_id"),
* #ORM\JoinColumn(name="Optios_id", referencedColumnName="Optios_id"),
* )
*/
private $pack;
/**
* #ORM\Column(type="boolean", name="Deleted")
*/
private $deleted;

Symfony3 class inheritance and db relationships

I have these 3 entitites
Users.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Users
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UsersRepository")
*/
class Users
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, unique=true)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=20)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="phone", type="string", length=20)
*/
private $phone;
/**
* #var string
*
* #ORM\Column(name="type", type="string")
*/
private $type;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var int
*
* #ORM\Column(name="feedback", type="integer")
*/
private $feedback;
/**
* #var string
*
* #ORM\Column(name="picture", type="blob")
*/
private $picture;
/**
* #var int
*
* #ORM\Column(name="rating", type="integer", length=255)
*/
private $rating;
/**
* #var string
*
* #ORM\Column(name="info", type="text")
*/
private $info;
/**
* #var \DateTime
*
* #ORM\Column(name="datecreated", type="datetime")
*/
private $datecreated;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
}
client.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* client
*
* #ORM\Table(name="client")
* #ORM\Entity(repositoryClass="AppBundle\Repository\clientRepository")
*/
class client extends Users
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="numberofjobsposted", type="integer")
*/
private $numberofjobsposted;
/**
* #var string
*
* #ORM\Column(name="clienttype", type="string", length=255)
*/
private $clienttype;
}
sprovider.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* sprovider
*
* #ORM\Table(name="sprovider")
* #ORM\Entity(repositoryClass="AppBundle\Repository\sproviderRepository")
*/
class sprovider extends Users
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var array
*
* #ORM\Column(name="interestedin", type="simple_array")
*/
private $interestedin;
/**
* #var int
*
* #ORM\Column(name="numofsuccjobs", type="integer")
*/
private $numofsuccjobs;
/**
* #var string
*
* #ORM\Column(name="sprovidertype", type="string", length=255)
*/
private $sprovidertype;
/**
* #var string
*
* #ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* #var string
*
* #ORM\Column(name="postcode", type="string", length=255)
*/
private $postcode;
}
So I achieved that the extends statement provides the Users properties in the client and sprovider tables in MySQL. That's awesome. What I want now is to make the relations so that when I add a new client for example, both the tables Users and client add a new user/client in MySQL, and they have same id too.
the type() property in the Users entity i would like to be optional for the type of user I create. Example : I create a new client and in the Users table in MySQL the type is set to "CLIENT".
I read this and so far I think it has to be ManyToMany relation but It's quite confusing to me.
How to make those relations in the entities and then how to use them in the controller? If possible, please provide an example.
I think you're confused about the reasons to use inheritance.
The idea is that you have base class, in this case User, and that can be extended to provide variations of that class, in this case client (you should capitalise this) and sprovider.
Ideally, you would not have a User table, only the other 2.
In doctrine, this is called a mapped super-class.
A mapped superclass is an abstract or concrete class that provides persistent entity state and mapping information for its subclasses, but which is not itself an entity. Typically, the purpose of such a mapped superclass is to define state and mapping information that is common to multiple entity classes.
see the documentation here
you can link properties using relationships, this is their example.
<?php
/** #MappedSuperclass */
class MappedSuperclassBase
{
/** #Column(type="integer") */
protected $mapped1;
/** #Column(type="string") */
protected $mapped2;
/**
* #OneToOne(targetEntity="MappedSuperclassRelated1")
* #JoinColumn(name="related1_id", referencedColumnName="id")
*/
protected $mappedRelated1;
// ... more fields and methods
}
/** #Entity */
class EntitySubClass extends MappedSuperclassBase
{
/** #Id #Column(type="integer") */
private $id;
/** #Column(type="string") */
private $name;
// ... more fields and methods
}

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

Nested jointable joincolumns in symfony 2 with doctrine 2

So given the entity Comment, what is the cleanest way to get the CommentPerson to find out if the CommentPerson isModerator()?
Without getting your fingers dirty using a repository.
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\CommentRepository")
* #ORM\Table(name="comment")
*/
class Comment
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $user_id; //id of entity User
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
**/
protected $user; //a user can have many comments
/**
* #ORM\Column(type="text")
*/
protected $commentText;
}
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\UserRepository")
* #ORM\Table(name="user")
*/
class User //this is the web user
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $person_id; //id of entity Person
/**
* #ORM\ManyToOne(targetEntity="Person")
* #ORM\JoinColumn(name="person_id", referencedColumnName="id")
**/
protected $person; //many web users can map to one actual person
public function getPerson()
{
return $this->person;
}
}
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\PersonRepository")
* #ORM\Table(name="person")
*/
class Person
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="text")
*/
protected $email;
/**
* #ORM\OneToMany(targetEntity="CommentPerson", mappedBy="person")
* #ORM\JoinColumn(name="id", referencedColumnName="person_id")
*/
private $commentPersons; //one person can have many commentPersons (since one person can be part in many different comment sections, not shown in code here, but take it as a fact)
}
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\CommentPersonRepository")
* #ORM\Table(name="comment_Person")
*/
class CommentPerson
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $person_id; //this is the id of the entity Person
/**
* #ORM\Column(type="boolean")
*/
protected $isModerator;
}

Categories