Doctrine isDeletable method in essence

I have Entity in my database (e.g. Member), which has many relationships with other tables (more precisely, 6 relationships). I don’t want to correlate some of them with ORM (I mean Entity), because they can have many records (for example, MemberAccessLogs), and some others load many other objects.

Now I want this Member Entity to have an isDeletable method, so I can disable the exception button on the administration page.

If I where to do it in the traditional way, I would have to declare associations with all other tables of the entity class, including MemberAccessLogs, and I would put this method in it so that I could check whether these associations are empty.

But AFAIU, I would have to make a selection (or at least an account) in the association tables to check the order for empty.

Another way would be to get the list that I want to show, and then make a separate request to check the empty with low cost (select * from the limit of table 1) in these sub-tables, and then populate the isDeletable method in Member programmatically before passing it Twig.

But I found this decision cumbersome. Does anyone have a better way to do this?

Just for the record: some people might think that this is "premature optimization." I argue (contrary to some) that you should think ahead when programming, and that is bad. But I really think this is not the place to discuss this. Please allow me to focus on the question that asked the question? :)

Edit

To easily prove that limit 1 is indestructibly faster than a counter, I did a little test on a table in my database that contains more than 20 million rows. Here are the results:

select count(*) from loga [20 million+ table] 20678473 1 row(s) fetched - 27023ms select exists(select null from loga limit 1) true 1 row(s) fetched - 2ms 

I think 13511.5 times faster is convincing enough .: D

+6
source share
1 answer

Extra lazy

You can peek into lazy associations .

Basically, you map all associations, as usual, and add fetch="EXTRA_LAZY" :

 /** * @Entity */ class CmsGroup { /** * @ManyToMany(targetEntity="CmsUser", mappedBy="groups", fetch="EXTRA_LAZY") */ public $users; } 

Now, Doctrine will not load the complete collection into memory on first access, but it will do specialized requests to load the parts that you really need at the moment.

So, $users->count() (or count($users) ) in the collection will cause a simple request count instead of loading the complete collection into memory.

afterload

You can use the postLoad event to determine if this object can be deleted. This postLoad event is postLoad after the entity has been created by EntityManager, therefore, when the entity has been loaded.

Add the unmapped property ( $isDeletable ) to an object that stores whether the object can be deleted or not.

Create an object listener that listens for the postLoad event. The listener may have an EntityManager, DBAL Connection, or something else that is being entered. With this dependency, you can execute any query you want and use the result to set $isDeletable .

The result is one additional request when the object is loaded, after which the entity “knows” whether it is deleted or not.

An example of using the postLoad event can be found in the Cookbook entry in the strategy template.

Note that under conditions that determine whether it is deleted or not changed, the value of $isDeletable may become incorrect. To solve this problem, you can track these conditions:

Keep track of

Add the associated property ( $isDeletable ) to an object that stores whether the object can be deleted or not. It will probably start with true .

When something is added to the association, which means the object is no longer being deleted, set $isDeletable to false .

When something is removed from the association, which means the object is deleted again, set $isDeletable to true .

In other words: every time you change, you track whether the object is deleted or not.

This way you will not need additional queries.

Here 's a cookbook entry in summary fields that explains this concept very well.

+5
source

All Articles