Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble Adding A Calculated Column to Object Model #1386

Closed
crossan007 opened this issue Jun 5, 2017 · 1 comment
Closed

Trouble Adding A Calculated Column to Object Model #1386

crossan007 opened this issue Jun 5, 2017 · 1 comment

Comments

@crossan007
Copy link
Contributor

crossan007 commented Jun 5, 2017

Scenario

I'm trying to store the return value of a method in an ActiveRecordInterface object into a virtualColumn on that object at hydration time so that it's included in the JSON formatter, and I'm having some trouble with two things.

The only seemingly-relevant, but not totally clear help I've found is this: http://howcanfix.com/14251/symfony-app-how-to-add-calculated-fields-to-propel-objects

First, the Object model code:

class Family extends BaseFamily
{
 public function getFamilyString()
    { 
        return "sometext";
   }
 public function hydrate($row, $startcol = 0, $rehydrate = false)
    {
      $r = parent::hydrate($row, $startcol, $rehydrate);
      $this->setVirtualColumn("FamilyString", $this->getFamilyString());
      return $r;
    }   
}

Full code here: https://github.com/ChurchCRM/CRM/blob/master/src/ChurchCRM/model/ChurchCRM/Family.php

and related schema (simplified)"

   <table name="family_fam" idMethod="native" phpName="Family" >
      <column name="fam_ID" phpName="Id" type="SMALLINT" size="9" sqlType="mediumint(9) unsigned" primaryKey="true"
                autoIncrement="true" required="true"/>
   </table>
    <table name="person_per" idMethod="native" phpName="Person" >
        <foreign-key foreignTable="family_fam">
            <reference local="per_fam_ID" foreign="fam_ID"/>
        </foreign-key>
    </table>

Full Schema here: https://github.com/ChurchCRM/CRM/blob/master/propel/schema.xml

Issue 1:

When I access this with a standard query from the associated FamilyQuery class and run through the toJSON parser, I receive a fully hydrated object in JSON format (including fully hydrated Person Objects:

$family = FamilyQuery::create()->findPk($args['familyId']);
      
        return $response->withJSON($family->toJSON());

Is there a way to prevent the entire contents of the related object from being formatted in the JSON output? I'd prefer to have only the Family object hydrated, and the value for FamilyString - not an array of each family member.

Issue 2:

With a table Pledges related to the Family table, I don't want to hydrate the entire Family object - I'm only interested in the FamilyString virtual column that was added during the Family object's hydration.

If I use ->joinWithFamily(), the entire family object (including the FamilyString) virtual column is hydrated and included in the resultant JSON output.

            ->filterByDepid($id)
            ->groupByGroupkey()
            ->withColumn('SUM(Pledge.Amount)', 'sumAmount')
            ->joinWithFamily(null, Propel\Runtime\ActiveQuery\Criteria::LEFT_JOIN)
            ->joinDonationFund()
            ->withColumn('DonationFund.Name')
            ->find()
            ->toJSON();

If I use ->joinFamily(), there does not seem to be a way to select only the FamilyString Virtual column.

Is there a way to select from a joined table, a single virtual column that was added during the related object's hydration for inclusion in toJSON()?

The full set of what I'm trying to accomplish is here: ChurchCRM/CRM#2564

@crossan007
Copy link
Contributor Author

crossan007 commented Jun 6, 2017

@benbankes suggested that I, instead of attempting to add the field at hydration time, add the field when the object is serialized into an array.

The resultant code on the Family model/class looks something like this: We are overriding the parent's toArray() method; invoking the parents method, and then altering the parent's return before passing the array to the application:

public function toArray()
{
      $array = parent::toArray();
      $array['FamilyString']=$this->getFamilyString();
      return $array;
}

Since the native toJSON() method actually calls the object's toArray() method, this solution worked for me to provide the calculated field I required to my API endpoint without including client-side manipulation, neither in the browser, nor in the client-code that invokes the Propel models.

The full set of changes I made to accomplish this "virtual calculated column" is here: https://github.com/ChurchCRM/CRM/pull/2564/files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant