Search code examples
mysqlpropelpropel2

Propel object collection bind column alias to the foreign table object insted of getting it out


I have two db tables one is Item and the other (Unit) is represent all the measure units available for Item table. In this scenario Item table contains a foreign key of Unit table which acts as one to many relation.

With Propel ORM I can join both tables like below and get json result:

$items = ItemQuery::create()
            ->joinWith('Item.Unit')
            ->withColumn("CONCAT (Unit.Name,'-',Unit.Label)", "MUnit")
            ->find()
            ->toJSON(); 

The output result will be:

{
   "Items":[
      {
         "Id":2,
         "Code":"M000002",
         "Name":"Item 1",
         "Price":234,
         "UnitId":1,
         "Status":true,
         "MUnit":"Kilograms-Kg",
         "Unit":{
            "Id":1,
            "Name":"Kilograms",
            "Label":"Kg",
            "Status":true
         }
      },
      {
         "Id":3,
         "Code":"M000003",
         "Name":"Item 2",
         "Price":100,
         "UnitId":2,
         "Status":true,
         "MUnit":"Meter-Mt",
         "Unit":{
            "Id":2,
            "Name":"Meter",
            "Label":"Mt",
            "Status":true
         }
      }
   ]
}

As you can see the column alias MUnit comes out from the unit object to the parent object. But what I exactly need is to keep the alias inside the Unit object like below.

...

 "Items":[
      {
         "Id":2,
         "Code":"M000002",
         "Name":"Item 1",
         "Price":234,
         "UnitId":1,
         "Status":true,
         "Unit":{
            "Id":1,
            "Name":"Kilograms",
            "Label":"Kg",
            "Status":true,
            "MUnit":"Kilograms-Kg",// here goes...
         }
      },
       ...

Any suggestion to achieve the expected out-put would be appreciable. Thank you.

UPDATE

If I change my code to result object collection, then the output will be :

$items = ItemQuery::create()
            ->joinWith('Item.Unit')
            ->withColumn("CONCAT (Unit.Name,'-',Unit.Label)", "MUnit")
            ->find();

Output:

...

#data: array:2 [▼
    0 => Item {#323 ▼
      #new: false
      #deleted: false
      #modifiedColumns: []
      #virtualColumns: array:1 [▼
        "MUnit" => "Kilograms-Kg" // <--- virtual column
      ]
      #id: 2
      #code: "M000002"
      #name: "Item 1"
      #price: 234.0
      #unit_id: 1
      #status: true
      #aUnit: Unit {#324 ▼
        #new: false
        #deleted: false
        #modifiedColumns: []
        #virtualColumns: []
        #id: 1
        #name: "Kilograms"
        #label: "Kg"
        #status: true
        #collItems: ObjectCollection {#325 ▶}
        #collItemsPartial: true
        #alreadyInSave: false
        #itemsScheduledForDeletion: null
      }

...

So what I exactly need is to get the virtualColumn MUnit into the Unit object.


Solution

  • Below approach worked for me :

    $items = \ItemQuery::create()
                ->joinWith('Item.Unit')
                ->withColumn("CONCAT (Unit.Name,'-',Unit.Label)", "MUnit")
                ->find();
            foreach ($items as $i) {
                $i->getUnit()->setVirtualColumn('Asdf', $i->getVirtualColumn('MUnit'));
            }
            dd($items->toJSON());
    

    Result Output :

    ...
    
     "Items":[
          {
             "Id":2,
             "Code":"M000002",
             "Name":"Item 1",
             "Price":234,
             "UnitId":1,
             "MUnit":"Kilograms-Kg",
             "Status":true,
             "Unit":{
                "Id":1,
                "Name":"Kilograms",
                "Label":"Kg",
                "Status":true,
                "Asdf":"Kilograms-Kg",// here goes...
             }
          },
           ...