Doctrine ORM -Remove attribute from entity? - symfony

Very simple thing I want to do, however I fail to find a solution.
I have started to develop my app with Symfony4 bundled with Doctrine. At the beginning I have designed database model but during development I have realized original solution is wrong way for what I want to do. Right now, I want to remove an attribute from entity. In plain SQL I would do ALTER TABLE table DROP COLUMN column then recreate it again with new parameters. However this solution gave me an error in Doctrine, so I have changed PHP model as well. Again, another error. Okay, so this does not look like the way I want to go.
Is there any solution to my problem, except digging too deep in Doctrine? Best would be something simple like described in the SQL command above?

When it comes to doctrine with symfony you should forget about tables, columns etc.. and start thinking with objects (otherwise there's no point in using doctrine for abstraction). For your problem you should simply remove the attribute in your entity.
Then You should use :
php bin/console doctrine:migrations:diff
Which will generate a migration file under the /migrations folder. This file will contain the SQL that doctrine will execute. It allows you to verify if the query is what you expect, if not you can directly modify it in that file or adapt your entity and generate a new migration file.
When you are happy with it, you can execute it with :
php bin/console doctrine:migrations:migrate

Related

Symfony doctrine reverse engineering and Apiplatform

Is there a way to create Apiplatform enabled entities directly from database schemas?
I successfully create the entities using php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity , but now i have to add manually the reference to Apiplatform resources in 120 entities like here. Is there another way?
Thanks in advance.
This feature isn’t supported out of the box (but it would be nice to add it). There is an open issue to add this feature to MakerBundle, but this hasn’t been implemented at time of writing.
However, you can easily achieve the same effect by using the "search and replace" feature of your IDE or by using sed: find every occurrences of #ORM\Entity and replace them with:
#ORM\Entity
#\ApiPlatform\Core\Annotation\ApiResource
You may want to run PHP CS Fixer after that to change the fully qualified class name by a use statement.

Can I use Code First Migrations without pluarized table names?

We finally got things squared away so that we can start using code first.
When I run "Enable-Migrations" it creates a file with InitialCreate in it's name.
(like here: http://msdn.microsoft.com/en-us/data/jj591621.aspx#enabling)
That file has plural database table names instead of singular.
I do have this line in my initiazlizer, which is correct:
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
but the file that is being created with the migration has all pluralized names.
This becomes annoying when I add a migration and the first thing it does is drop every pluralized table in the DB and re-add them as singular.
Can I pass a parameter into the "Enable Migrations" command or something to tell it to not pluralize?
This behavior has been fixed, I'm unable to reproduce it with EF 6.1.0. I created the database using an initializer first, than ran Enable-Migrations (of course OnModelCreating() already includes the line removing the PluralizingTableNameConvention). The generated migration (with InitialCreate in its name) generates tables named in the singular. So if you're able to update EF your problem will be gone.
If not: did you try to override the table names with their singular form using the Table attribute? At least generated migration code does respect it (I haven't checked with an older EF version than 6.1.0 though).
[Table("MyEntity")]
public class MyEntity
{
// .. your properties go here.
}

Use FOSUserBundle in relation with yml-based Entities

I've started a Symfony2 project from scratch where I then installed FOSUserBundle.
Then, I have written (actually, generated with ORM Designer) some entities that need to have relations between them, and with the User entity.
I have Items belonging to Users, Collections belonging to Users that group Items, and so on.
Since I used FOSUserBundle I only have a basic User class (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md , step 3a) defined using annotations, no config/doctrine folder and no User.yml file in it.
I then created the MyBundle/Resources/config/doctrine folder and added the yml files mentioned above.
When I try to generate the entities with the command-line tool everything works fine: it will create the Entities from my yml files.
However, at this point, trying to load up in browsers the url where the login previously worked (when I only had the FOSUserBundle installed) will throw this error:
MappingException: No mapping file found named
'/var/www/concert/src/X/MyBundle/Resources/config/doctrine/User.orm.yml'
for class 'X\MyBundle\Entity\User'.
Following actions, such as generating the CRUD logic, will not work as long as I have an *.orm.yml file in the config/doctrine folder. If I remove those, CRUD generation will work, but generation of actual mysql tables won't.
Juggling with these gets me to a point where I can also get the tables, but then the actual app doesn't work if I try to use any of the url's where the newly generated CRUD is involved because since the entities are based on yml (which I remove to get things "working") it won't have any mapping knowledge.
Is this inherently wrong? To have yml-based entities in relationship with an User entity based on the FOSUserBundle and still be able to get the nice command-line generation tools?
The problem you describe stems from mixing configuration formats (yaml and I assume annotations). You can easily fix this by ditching the annotations in your models and replacing them with yaml-files like you would do in your own models.
Unfortunately the FOSUserBundle-docs only show you how to use annotations, so here is a quick transformation into yaml format when your X\MyBundle\Entity\User extends FOSUSerBundle's UserEntity:
X\MyBundle\Entity\User:
type: entity
table: fos_user
id:
id:
type: integer
strategy: { generator: "AUTO" }
The remaining stuff is taken care of by FOSUserBundle, as the BaseModel is a mapped-superclass and already describes the stuff in the User.orm.xml, but you could just as well replace the existing values or add additional values just like you would do with your own models.
If you don't use annotations throughout your app, you might also want to disable them in your app/config/config.yml to prevent side effects.

use generated entities as "base class" in sf2/doctrine2

How can I tell Doctrine2 Entity Manager to use an inherited class by default, instead of the generated one?
In my new sf2 app, I generated all entities from the existing database to /src/Package/Bundle/DataBundle/Entity - of course I'd like to have generated forms as well, so I need for my foreign-key relations __toString() methods, which I don't want to put into those generated files because they get overwritten (yes they also get backuped in an extra file, so my changes aren't lost, but manually merging files is not what I want).
So I added new classes to /src/Package/Bundle/DataBundle/Model inheriting all from the entities, but with a __toString() method and surely some other tweaks in the future as well. But now, when I call $entity = $em->getRepository('PackageDataBundle:Customer')->find($id); - I get an instance of /src/Package/Bundle/DataBundle/Entity/Customer instead of /src/Package/Bundle/DataBundle/Model/Customer ..
I'd like to have the behaviour from sf1, where all custom work is done in the inherited classes and the generated ones are the "base" Classes, which can be updated any time on a schema update and aren't touched otherwise..
I hope there is some configuration for this..
Maybe as a bonus, I'd like to have my naming convention turned around: to have Model as the "abstract" generated one and Entity as the actual used one
Thanks.
I'd like to have the behaviour from sf1, where all custom work is done in the inherited classes and the generated ones are the "base" Classes, which can be updated any time on a schema update and aren't touched otherwise..
For purposes you described you should use Propel ORM - it was so in Symfony-1.4, and became even more flexible for Symfony-2.0 with Propel 1.6. It is well documented, easily installed and naturally used within Symfony-2.0
Perhaps I misunderstood your problem, but going from Propel to Doctrine i was also disappointed that there is no way to keep that "dirty" auto-generated code out of my logic.
I do not know how much it is now important to you, but I currently writing a simple bundle that implements such generation style.
$ app/console doctrine:generate:entities СompanySomeBundle --propel-style=true
Generating entities for bundle "СompanySomeBundle"
> backing up User.php to User.php~
> generating Сompany\SomeBundle\Entity\Base\User
> generating Сompany\SomeBundle\Entity\User
https://github.com/madesst/MadesstDoctrineGenerationBundle
PS: Sorry for my english =/

How do I exclude the Scheme name from SqlMetal generated Objects?

SqlMetal is creating object names such as...
The View:
Sales.ProductDescription
is created as:
Sales_ProductDescription
Ideally SqlMetal would create the ProductDescription class under a namespace .Sales. but thats probably too much to ask for. So is there anyways to get it to create the class without the sheme prefix such as "ProductDescription".
Thanks,
Justin
This would involve some modifications to the DBML file after it's been generated. However, in terms of maintainability that might restrict your ability to quickly regenerate when the schema changes.
If you have a volatile schema you could check out this collection of powershell scripts I wrote some time ago that will handle such changes to the DBML. It takes an XML file as input. Warning: the sample in the code repository may be out of date, but the scripts certainly work - I still use them.
SqlMetal has an optional parameter to include a namespace. The default value is no namespace. Check out this link on MSDN.
http://msdn.microsoft.com/en-us/library/bb386987.aspx

Resources