EasyCorp / EasyAdminBundle

EasyAdmin is a fast, beautiful and modern admin generator for Symfony applications.
MIT License
4.09k stars 1.03k forks source link

Doctrine relation - link / no link to entity #367

Closed arukado-sama closed 9 years ago

arukado-sama commented 9 years ago

Hi everyone!

I don't understand why some of my entities get a link when linked to an other entity by a doctrine relation, and some don't.

Here is an example:

/**
   * @var Client
   * @ORM\ManyToOne(targetEntity="Client")
   * @ORM\JoinColumn(name="c_id", referencedColumnName="c_id", onDelete="cascade")
   */
  protected $cId;

  /**
   * @var User
   * @ORM\ManyToOne(targetEntity="Groupware\UserBundle\Entity\User")
   * @ORM\JoinColumn(name="pm_resp_id", referencedColumnName="id", onDelete="cascade")
   */
  protected $respId;

screenshot from 2015-06-24 10 52 51

respId (Responsable) has a link but cId (Client) hasn't. The __toString() methods are the same. respId is in an other bundle but I don't think it's the problem.

Pierstoval commented 9 years ago

IIRC, it's because EasyAdmin generates a link only if the entity is editable in the back-end, but I'm not entirely sure. Ping @javiereguiluz

arukado-sama commented 9 years ago

My two entities are editable. I have to add that the first relation (on Client) is a bit older than the second (on User). It causes this with all of my old relations so I don't know if it's an easy-admin's update problem. I never had links before, now all my new relations have links. Maybe I should try to re-generate my database?

Pierstoval commented 9 years ago

Relations are managed by Doctrine, so first you should check that your entities' relation mapping is correct, and then check that Doctrine is ok with it by running app/console doctrine:schema:validate. If a relation is not correct, then the generated doctrine metadatas will be incorrect. Plus, don't forget to clear the entire cache when changing the mapping, so everything is clean.

arukado-sama commented 9 years ago

I always clear my cache. Don't know why but when I try to update database schema there always are queries:

root@devintranet:/var/www/Symfony# app/console doctrine:schema:update --force
Updating database schema...
Database schema updated successfully! "19" queries were executed
root@devintranet:/var/www/Symfony# app/console doctrine:schema:update --force
Updating database schema...
Database schema updated successfully! "19" queries were executed

I think it's because of some ORM overrides on entities (to transform fields to unique).

So when I want to validate the schema:

root@devintranet:/var/www/Symfony# app/console doctrine:schema:validate
[Mapping]  OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current mapping file.
Pierstoval commented 9 years ago

What kind of DBMS are you using? Note that if you are using sqlite, it's normal. But for MySQL, it's not normal. You should first check what are the sql queries by using app/console d:s:u --dump-sql

arukado-sama commented 9 years ago

I'm using mysql with phpmyadmin.

Here is the output:

root@devintranet:/var/www/Symfony# app/console d:s:u --dump-sql
ALTER TABLE ce_tache ADD CONSTRAINT FK_4AB576395862D41C FOREIGN KEY (ph_id) REFERENCES ce_phase (ph_id) ON DELETE CASCADE;
ALTER TABLE ce_bl_row ADD CONSTRAINT FK_3F909A6ECD2087A9 FOREIGN KEY (bl_id) REFERENCES ce_bl (bl_id) ON DELETE CASCADE;
ALTER TABLE ce_ordre_mis ADD CONSTRAINT FK_E6B9CC5E6FBC242E FOREIGN KEY (pm_id) REFERENCES ce_projet (pm_id) ON DELETE CASCADE;
ALTER TABLE ce_ordre_mis ADD CONSTRAINT FK_E6B9CC5EAF0627F3 FOREIGN KEY (om_statut) REFERENCES ce_ordre_mis_etat (om_statut);
ALTER TABLE ce_bc_row ADD CONSTRAINT FK_BDC00DBF954397FF FOREIGN KEY (bc_id) REFERENCES ce_bc (bc_id) ON DELETE CASCADE;
ALTER TABLE ce_proto_out ADD CONSTRAINT FK_70B9F22867C663E7 FOREIGN KEY (pr_id) REFERENCES ce_prototype (pr_id) ON DELETE CASCADE;
ALTER TABLE ce_phase ADD CONSTRAINT FK_688F8087C00A36A FOREIGN KEY (d_id) REFERENCES ce_devis (d_id) ON DELETE CASCADE;
ALTER TABLE ce_phase ADD CONSTRAINT FK_688F8087175E667D FOREIGN KEY (ph_livree) REFERENCES ce_phase_livree (ph_livree);
ALTER TABLE ce_phase ADD CONSTRAINT FK_688F80875B6EF206 FOREIGN KEY (ph_etat) REFERENCES ce_devis_etat (d_etat);
ALTER TABLE ce_bl ADD CONSTRAINT FK_6067B06A6FBC242E FOREIGN KEY (pm_id) REFERENCES ce_projet (pm_id) ON DELETE CASCADE;
ALTER TABLE ce_br ADD CONSTRAINT FK_9A688D096FBC242E FOREIGN KEY (pm_id) REFERENCES ce_projet (pm_id) ON DELETE CASCADE;
ALTER TABLE ce_devis ADD CONSTRAINT FK_521593676FBC242E FOREIGN KEY (pm_id) REFERENCES ce_projet (pm_id) ON DELETE CASCADE;
ALTER TABLE ce_devis ADD CONSTRAINT FK_52159367EC6A9C8B FOREIGN KEY (d_etat) REFERENCES ce_devis_etat (d_etat);
ALTER TABLE ce_bc ADD CONSTRAINT FK_F0D8ADFB6FBC242E FOREIGN KEY (pm_id) REFERENCES ce_projet (pm_id) ON DELETE CASCADE;
ALTER TABLE ce_bc ADD CONSTRAINT FK_F0D8ADFBD26628FA FOREIGN KEY (exp_id) REFERENCES vcards (id) ON DELETE CASCADE;
ALTER TABLE ce_bc ADD CONSTRAINT FK_F0D8ADFB79839897 FOREIGN KEY (dest_id) REFERENCES vcards (id) ON DELETE CASCADE;
ALTER TABLE ce_prototype ADD CONSTRAINT FK_8E6D162F923D3FB FOREIGN KEY (pr_etat) REFERENCES ce_proto_etat (pr_etat);
ALTER TABLE ce_prototype ADD CONSTRAINT FK_8E6D1626FBC242E FOREIGN KEY (pm_id) REFERENCES ce_projet (pm_id) ON DELETE CASCADE;
ALTER TABLE ce_br_row ADD CONSTRAINT FK_E040B38D7DE6A705 FOREIGN KEY (br_id) REFERENCES ce_br (br_id) ON DELETE CASCADE;

I really don't understand why it needs to update constraints every time.

Pierstoval commented 9 years ago

For all these tables, what is the sql engine? InnoDB or MyISAM ?

arukado-sama commented 9 years ago

Where can I see my sql engine?

Nevermind, I think I found it:

screenshot from 2015-06-24 11 32 32

Pierstoval commented 9 years ago

Directly from your mysql database, run this query:

show table status where name = 'your_table_name';
arukado-sama commented 9 years ago

You were right, some of my tables are using an other engine:

screenshot from 2015-06-24 12 01 14

Pierstoval commented 9 years ago

You should then understand why some tables are in MyISAM and others are on InnoDB.

Basically, the difference between them are that MyISAM supports fulltext search, and InnoDB supports transactions and relations/foreign keys. Depending on what you need, maybe you'll need to change the different tables engines if you need proper mysql relations.

By the way, I don't know if Doctrine's metadatas differ when relations are not properly set in the database... My first thought would be "no" because it's mostly managed by the ORM, and sql structure is managed by the DBAL, but I'm not familiar enough with low-level Doctrine to say so...

First we need to check whether it's an EasyAdmin issue or a Doctrine issue.

arukado-sama commented 9 years ago

Do you think my ORM parameters are wrong for some entities? Validation says that mapping files are correct. Do I have to modify manually the table engines? I hope this is an easy-admin issue cause I really have no idea what is causing this. Moreover, all ce_projet, ce_client and users tables are in InnoDB.

Pierstoval commented 9 years ago

Yep, you have to update the engines manually, because when creating a table, Doctrine uses the default database engine, so it depends on your mysql configuration. If the default engine is MyISAM you may re-think about how you want your database to be used.

arukado-sama commented 9 years ago

Default is InnoDB but I know why there are MyISAM tables in my base, these tables are copied and modified from an other database (the source database I'm using to convert the project into a Symfony project). So I'll modify the engine for all these tables.

arukado-sama commented 9 years ago

Well, when I convert to InnoDB some tables can't be updated anymore, it gives me constraint errors. Why did it works before and why is it not working anymore? I checked my relations and everything seems correct. Maybe I should let them in MyISAM?

Pierstoval commented 9 years ago

Get the sql query with app/console d:s:u --dump-sql and run it, you need forced constraints, so wrap the sql query with this:

SET FOREIGN_KEY_CHECKS=0;
-- Your SQL query
SET FOREIGN_KEY_CHECKS=1;

It should create the constraints between the tables and resolve constraint issues with doctrine

arukado-sama commented 9 years ago

It worked, I just have to do this for all tables now (convert to InnoDB, utf-8, then repair constraints). Thanks for your help! (Although it doesn't solve the current issue about entity link)

arukado-sama commented 9 years ago

I'm currently trying to understand what is causing this issue. I checked my entities again and everything seems to be alright. Moreover all my tables are in InnoDB now.

EDIT: I finally understand what this bug really is. It seems that linked entities from the same bundle have no hypertext link, only other bundles entities get a link when associated with a field. It's a clue to find out a solution.

javiereguiluz commented 9 years ago

In order to display a link, these two conditions must be met:

  1. The related entity must be managed by EasyAdmin too.
  2. The related entity must have a getId() public method (if the primary key has a different name, then it must define a get+PrimaryKeyName method. For example: getClient())

This behavior was recently improved to fix some edge cases that produced errors, so it must now work as expected in every case. Feel free to reopen this issue (or create a new one) if you still have issues. Thanks.

feyyazesat commented 8 years ago

Hi,

I couldn't see the related entity link in the list view. So I did dig into the code.

In Twig Extension It gets targetEntityClassName but in configurator It tries to match with aliases. So it couldn't find entity, if aliasing used in config.

Using with simple configuration as mentioned here There is no problem but through extended configuration syntax. It looses the real class name.

khaledbouguerra commented 8 years ago

hey guys does any one knows why i'm getting this error when I try to add a knew row in my database "Catchable Fatal Error: Object of class AppBundle\Entity\Theme could not be converted to string" I get this error any when I try to add a row in a table that has a foreign key.

javiereguiluz commented 8 years ago

@khaledbouguerra you are probably missing a __toString() method in the Theme entity.

khaledbouguerra commented 8 years ago

I added it but still getting the same error. here's the code:

/**
     * toString
     * @return string
     */
    public function __toString()
    {
        return $this->getIdTheme();
    }
feyyazesat commented 8 years ago

@khaledbouguerra what type it is that getIdTheme() method returns ? If it is not string, the error will appear. You can use as following.

public function __toString() { return (string) $this->getIdTheme(); }