Specifying index with Symfony2 for Doctrine's PersistentCollection - symfony

Can anybody tell me how I can configure Symfony2/Doctrine to index objects within a PersistentCollection, from a specified column in the entity?
For example assume we have two tables; categories and products, with many products to one category. When I use the repository to load a category, and then call getProducts() to load the products, I want them to be returned indexed by the product ID, or whatever column I specify. Currently they're just indexed incrementally from zero.
Is there anyway to do this, or do I need to loop through and manually set the keys myself?

Mapping OneToMany associations allows you to define an indexBy property. With annotation mappings, it would look like following
class Category
{
// ...
/**
* #OneToMany(targetEntity="Products", indexBy="productId", mappedBy="product")
*/
protected $products;
// ...
}
XML, YAML and PHP mappings allow this too, and this works also with ManyToMany.

Related

Symfony Algolia Search Engine Association Indexing

I have a product entity, and each product is assigned to a category which is a separate category entity which is joined with a categoryId property in my product Entity. I have indexed all of the properties that I need such as name price etc, but I can't get my categoryId to index correctly:
When this it is indexed I get an array but not with the actual category Id or other information associated in that category:
So my question is, what is the correct way of going about this so that the category my product is assigned to is indexed correctly?
Thanks
You have two problems:
First:
You put on property and method, you must chose one.
Second:
With symfony when you make a ManyToOne like this
$this->categoryId
return an object, you can't map entire object with algolia attribute.
I suggest you to just make one method like this:
/*
* #Algolia\Attribute
*/
function getCategoryName() {
return $this->categoryId->getName();
}

Symfony2 and Doctrine - ManyToOne

I am trying to understand Symfony2, but there is something that is not making sense to me. I reversed engineered an existing database to produce my entities, so maybe thats the problem.
I have a table called availability_alert, nothing special, a few fields including an id (which is the primary key). This table has no link to anything else.
I then have a second table called booking_class, once again nothing special, but it does have the field $availabilityAlert which links to the availability_alerts tables id.
In essence, an Availability Alert can have one or many Booking Class.
Now in my booking class entity, I have the link
/**
* #var \AlertBundle\Entity\AvailabilityAlert
*
* #ORM\ManyToOne(targetEntity="AlertBundle\Entity\AvailabilityAlert")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="availability_alert_id", referencedColumnName="id")
* })
*/
private $availabilityAlert;
So this all looks ok. The setter for it though came out like so
public function setAvailabilityAlert(\AlertBundle\Entity\AvailabilityAlert $availabilityAlert = null)
{
$this->availabilityAlert = $availabilityAlert;
return $this;
}
So that appears to take an AvailabilityAlert Object as a parameter, not the AvailabilityAlert id?
So with the above, I am presuming doing something like this in my controller will not work?
$alert = new AvailabilityAlert();
$bookingClass = new BookingClass();
$bookingClass->setAvailabilityAlert($alert->getId());
Could someone give me some advice on whether things are correct here, or if I should be doing something else? Essentially AvailabilityAlert should be a static table, other tables link to this.
Any advice appreciated.
Thanks
Yes this is correct.
In the Doctrine world, you are working with objects, not with integers or strings, when it comes to relationships between Entities.
You can read more about Doctrine 2 relationships here: http://symfony.com/doc/current/book/doctrine.html#entity-relationships-associations
That's correct. You don't use integers, strings. It's because the relationships are given in entity annotations and Doctrine uses them to figure out what is used exactly to reference the one object from the other. This even let you change how objects reference themselves - for example you change the id to a compound primary key in AvailabilityAlert class and your code wouldn't change much except for the annotations.

Symfony2, Doctrine, Empty associative entity

Let' imagine we have several tables: table_item, table_category, table_items_status.
Which is updated by service in single mode (no relations) using their own entity.
Can i, and how, create one entity that will have only relatioship of this tables, for example something like that....
**
* #ORM\OneToOne(targetEntity="table_item")
* #ORM\JoinColumn(name="itemID", referencedColumnName="itemID")
**
private $tableItemIDByItemID
// ... getter\setter
**
* #ORM\Column(type="integer")
**
private $itemID;
// ... getter\setter
In php code i want simply call
$entity->setItemID(123);
$result = $entity->getTableItemIDByItemID();
And will get ArrayCollection() from table_item by itemID.
Main thing that I want create extra entity only with relationships for several tables and only unidirectional. I need this for creating entity without touching another for relationships.
You should look into entity repositories. These provide some basic functionality queries but you can extend them with your own custom queries (eg: getItemIDByItemID). It's called the repository pattern. An entity is just a object representation of your database.
Symfony2 manual:
"It's a good idea to create a custom repository class for your entity and add methods with your query logic there."
Some more information about repositories:
http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes
http://www.zalas.eu/doctrine2-and-symfony2

Doctrine generate code with other naming conventions

We are starting with Symfony2 and Doctrine. I need to select some data from tables that already exist. These tables and column names do not use the naming conventions as defined by Doctrine.
I was wondering if I could create my own naming scheme somewhere. Mainly, we use PascalCase table and columnnames, without underscored. This results in Entity properties like $firstpromotiondatetime while the column is FirstPromotionDateTime, so i'd like my property to be firstPromotionDateTime.
You don't necessarily need to use doctrine's entity generator to generate new entities, you can also manually do it. However, you can also generate the entities via the command line, and then open your entity classes and change the property names as you see fit. Just make sure that the doctrine mapping (use the following annotation for instance) is still pointing to the correct column name in your database.
/**
* #var \DateTime $firstPromotionDateTime
*
* #ORM\Column(name="FirstPromotionDateTime", type="datetime")
*/
private $firstPromotionDateTime;
Edit:
If you manually change the property names, also make sure you have correctly modified the setters & getters as well.

Implementing Doctrine many-to-many -- sometimes

I have a site with many Users and many Designs, each of which was created by one User. Users can also select other Designs as a favorite, and can go to a page that shows their favorites. So, there's a many-to-many relationship between Users and Designs termed "Favorite".
I'm wondering what the best way is to implement this Favorite relationship. I'm only ever looking for Favorites for a particular user, and only on one page. It seems that Doctrine defaults to returning an object with all its related objects, so I'm concerned that by adding this relationship I'll suddenly get a ton of extra objects added to all my Design list API calls.
Advice on how to set this up? I have repositories in place for all entities.
I'll share an implementation I have between Tags and Posts (Posts can have multiple tags, and each tag can be associated with more than one post). I think it's similar enough to get you started. It's super simple to setup:
In the Post entity, I have this:
/**
* #ManyToMany(targetEntity="Tag", inversedBy="posts")
* #JoinTable(name="activity_relationship",
* joinColumns={#JoinColumn(name="object", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="subject", referencedColumnName="id")}
* )
*/
protected $tags;
In the Tag entity, I have this:
/**
* #ManyToMany(targetEntity="Post", mappedBy="tags")
*/
protected $posts;
There no entity necessary for the joining table.
In the case of posts carrying tags, it's enough for me to just access the tags property since there will always be a small amount, but each tag is likely to have tons and tons of posts, so I want some LIMIT and OFFSET controls over this. For this reason, as Cerad mentioned above, you don't need to use the $posts variable directly, instead I query that separately using dql.
SELECT t
FROM Post p
JOIN p.tags t
<add whatever other stuff you want>
Whichever way you prefer to execute that query, you will probably have a query object from Doctrine, to apply the LIMIT and OFFSET, just do
$query->setMaxResults($limit);
$query->setFirstResult($offset);

Resources