Rúben Silva
Rúben Silva

Reputation: 21

Doctrine - Database representation

I tried almost everything trying to make Entities that represent my database schema and still having full page errors. If someone can give me some light I would appreciated.

Basically we have 2 registration forms, one for the brand and one for the influencer. In each form we ask for the user information PLUS the specific information depending on which form page you are.

DATABASE SCHEMA:

id | name

id | id_role FK| name | phone | email | password | created_at | status

id | user_id FK| name_brand | position_id | email_brand | nif_brand | name_firma | phone_brand |

id | name

id | name

id | user_id FK | surname | date_of_birth | email_brand | district_id FK | gender

MAIN POINTS:

I already tried to use Doctrine annotation and still didn't worked for me, not sure if it's because Im new to this or if Im not structuring the database/entities correctly or even the managing an entity with its associations into the database.

The idea is that ONE user/person can be EITHER a BRAND or INFLUENCER. That is achieved by the role_id which links to the role table. E.g, if i'm in the brand form and try add my information it will add the personal info in the users table and use the role_id 2 to link to the role table. The specific brand information given will then be inserted in the table BRAND using the user PRIMARY KEY to link both tables. (NOT SURE IF THERE'S A MISTAKE HERE, maybe the user should go through the role table and from that table to the specific table, which is not what i'm doing now). In the BRAND table I ask for it's info and coming from the POSITION SELECT in the form I get the FK position_id and link it to the table POSITION.

A different but similar thing happens with the influencer, which will select his district and then i use that district_id to link the districts table.

The problem is always the foreign key associations with doctrine and property's I need to define in the entities. I already don't declare the foreign keys because I'm aware that doctrine handles the FK relations internaly using objects but can't make this to work..

I would appreciate a lot all the help you guys can share. Thank you.

Upvotes: 0

Views: 86

Answers (1)

rkeet
rkeet

Reputation: 3468

I think you're trying to manually do what Doctrine can provide through inheritance.

A small setup that should work with your description of what you're trying to do.

Generic User setup

/**
 * @ORM\Table(name="users")
 * @ORM\Entity
 *
 * @ORM\MappedSuperclass

 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 */
class User 
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @var string
     * @ORM\Column(name="name", type="string", length=255, nullable=false, unique=true)
     */
    protected $name;

    /**
     * @var Position
     * @ORM\OneToOne(...)
     */
    protected $position; // TODO

    // getters/setters & other properties
}

Brand user

/**
 * @ORM\Table(name="brands")
 * @ORM\Entity
 */
class BrandUser extends User
{
    /**
     * @var string
     * @ORM\Column(name="specific_brand_property", type="string", length=255, nullable=false, unique=false)
     */
    protected $specificBrandProperty;

    // getters/setters & other properties
}

This small setup should already provide you with 2 Entity objects: User and BrandUser, where the latter expands the first.

The primary keys for BrandUser will be Foreign Keys to User and requirements of User are also requirements for BrandUser.

If you're using Fieldset and InputFilter classes you can have the BrandUserFieldset expand the Fieldset for use in your form (example below and more info in one of my repo's on this subject)

class UserFieldset
{
    public function init()
    {
        parent::init();

        $this->add([
            'name' => 'id',
            'required' => true,
            'type' => Hidden::class,
        ]);

        $this->add([
            'name' => 'name',
            'required' => true,
            'type' => Text::class,
            'options' => [
                'label' => 'Name',
            ],
        ]);

        $this->add([
            'name' => 'position',
            'required' => true,
            'type' => ObjectSelect::class,
            // other properties
        ]);
    }
}

Extended for BrandUser

class BrandUserFieldset extends UserFieldset
{
    public function init()
    {
        parent::init(); // <-- adds id, name, position

        $this->add([
            'name' => 'specificBrandProperty',
            'required' => true,
            'type' => Text::class,
            'options' => [
                'label' => 'Name',
            ],
        ]);
    }
}

Thought to add some commands, they might help you out. My setup requires me to prefix commands with ./vendor/bin/doctrine-module, add what you need for your setup to the following:

  • orm:validate-schema - will check your Doctrine Annotation for errors. Will also return any errors (syntax and logic) it finds
  • orm:schema-tool:update - command to create/update your database schema
    • flag -f - will make :update execute for real
    • flag --dump-sql will make :update not execute, but have the SQL dumped in your Terminal
    • flags -f and --dump-sql may be combined
  • orm:mapping:describe “\Full\Namespace\To\Entity” - Shows all information Doctrine has about a specific Entity - including relations, relation mappings, discriminators, extending (child) and parent entities, et cetera

Also, have a look at a solution I had for a similar problem some time ago.

Upvotes: 1

Related Questions