Symfony app - how to add calculated fields to Propel objects?

前端 未结 5 793
清酒与你
清酒与你 2021-02-10 03:41

What is the best way of working with calculated fields of Propel objects?

Say I have an object \"Customer\" that has a corresponding table \"customers\" and each column

5条回答
  •  一个人的身影
    2021-02-10 04:14

    There are several choices. First, is to create a view in your DB that will do the counts for you, similar to my answer here. I do this for a current Symfony project I work on where the read-only attributes for a given table are actually much, much wider than the table itself. This is my recommendation since grouping columns (max(), count(), etc) are read-only anyway.

    The other options are to actually build this functionality into your model. You absolutely CAN do this hydration yourself, but it's a bit complicated. Here's the rough steps

    1. Add the columns to your Table class as protected data members.
    2. Write the appropriate getters and setters for these columns
    3. Override the hydrate method and within, populate your new columns with the data from other queries. Make sure to call parent::hydrate() as the first line

    However, this isn't much better than what you're talking about already. You'll still need N + 1 queries to retrieve a single record set. However, you can get creative in step #3 so that N is the number of calculated columns, not the number of rows returned.

    Another option is to create a custom selection method on your TablePeer class.

    1. Do steps 1 and 2 from above.
    2. Write custom SQL that you will query manually via the Propel::getConnection() process.
    3. Create the dataset manually by iterating over the result set, and handle custom hydration at this point as to not break hydration when use by the doSelect processes.

    Here's an example of this approach

    prepareStatement( $sql );
            $rs = $stmt->executeQuery( array(), ResultSet::FETCHMODE_NUM );
    
            //  Create an empty rowset
            $rowset = array();
    
            //  Iterate over the result set
            while ( $rs->next() )
            {
                //  Create each row individually
                $row = new Table();
                $startcol = $row->hydrate( $rs );
    
                //  Use our custom setter to populate the new column
                $row->setCalcCol( $row->get( $startcol ) );
                $rowset[] = $row;
            }
            return $rowset;
        }
    }
    

    There may be other solutions to your problem, but they are beyond my knowledge. Best of luck!

提交回复
热议问题