Search code examples
phpmysqlsqlpropel

Way to exclude a joined relation object from the result set in Propel?


I have 4 tables, that represent a simple survey db setup:

table name: (delimited columns)
---------------------------------------------------------------
survey: (id, title)
surveyQuestion: (id, title)
surveyAnswer: (id, surveyQuestionID, title, sortOrder)
surveyToSurveyQuestion: (surveyID, surveyQuestionID, sortOrder)

Here is a query I use to pull all of the surveys with all related questions and answers:

$query = SurveyQuery::create()
    ->joinWith('SurveyToSurveyQuestion')
    ->useSurveyToSurveyQuestionQuery()
        ->orderBySurveyId()
        ->orderBySortOrder()
        ->joinWith('SurveyQuestion')
        ->useSurveyQuestionQuery()
            ->joinWith('SurveyAnswer')
            ->useSurveyAnswerQuery()
                ->orderBySortOrder()
            ->endUse()
        ->endUse()
    ->endUse();

However, many-to-many 'SurveyToSurveyQuestion' relation gets bloated as I add more surveys, specially if surveys share questions.

Is there a way to exclude the 'SurveyToSurveyQuestion' data from the result dataset?

Edit:

Attaching the db schema.

<table name="survey" idMethod="native" phpName="Survey">
    <column name="id" phpName="Id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
    <column name="statusID" phpName="StatusID" type="INTEGER" required="true"/>
    <column name="code" phpName="Code" type="VARCHAR" required="true"/>
    <column name="createdDate" phpName="CreatedDate" type="TIMESTAMP" default="0000-00-00 00:00:00"/>
    <index name="INDEX_StatusID">
        <index-column name="statusID"/>
    </index>
    <foreign-key foreignTable="status">
        <reference local="statusID" foreign="id"/>
    </foreign-key>
    <vendor type="mysql">
        <parameter name="Engine" value="InnoDB"/>
    </vendor>
</table>
<table name="surveyQuestion" idMethod="native" phpName="SurveyQuestion">
    <column name="id" phpName="Id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
    <column name="surveyQuestionTypeID" phpName="SurveyQuestionTypeID" type="INTEGER" required="true"/>
    <column name="code" phpName="Code" type="VARCHAR" required="true"/>
    <index name="INDEX_SurveyQuestionTypeID">
        <index-column name="surveyQuestionTypeID"/>
    </index>
    <foreign-key foreignTable="surveyQuestionType">
        <reference local="surveyQuestionTypeID" foreign="id"/>
    </foreign-key>
    <vendor type="mysql">
        <parameter name="Engine" value="InnoDB"/>
    </vendor>
</table>
<table name="surveyQuestionType" idMethod="native" phpName="SurveyQuestionType">
    <column name="id" phpName="Id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
    <column name="title" phpName="Title" type="VARCHAR" required="true"/>
    <vendor type="mysql">
        <parameter name="Engine" value="InnoDB"/>
    </vendor>
</table>
<table name="surveyAnswer" idMethod="native" phpName="SurveyAnswer">
    <column name="id" phpName="Id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
    <column name="surveyQuestionID" phpName="SurveyQuestionID" type="INTEGER" required="true"/>
    <column name="code" phpName="Code" type="VARCHAR" required="true"/>
    <column name="sortOrder" phpName="SortOrder" type="INTEGER"/>
    <index name="INDEX_SurveyQuestionID">
        <index-column name="surveyQuestionID"/>
    </index>
    <foreign-key foreignTable="surveyQuestion">
        <reference local="surveyQuestionID" foreign="id"/>
    </foreign-key>
    <vendor type="mysql">
        <parameter name="Engine" value="InnoDB"/>
    </vendor>
</table>
<table name="surveyToSurveyQuestion" idMethod="native" phpName="SurveyToSurveyQuestion">
    <column name="id" phpName="Id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
    <column name="surveyID" phpName="SurveyID" type="INTEGER" required="true"/>
    <column name="surveyQuestionID" phpName="SurveyQuestionID" type="INTEGER" required="true"/>
    <column name="sortOrder" phpName="SortOrder" type="INTEGER"/>
    <index name="INDEX_SurveyID">
        <index-column name="surveyID"/>
    </index>
    <index name="INDEX_SurveyQuestionID">
        <index-column name="surveyQuestionID"/>
    </index>
    <foreign-key foreignTable="survey">
        <reference local="surveyID" foreign="id"/>
    </foreign-key>
    <foreign-key foreignTable="surveyQuestion">
        <reference local="surveyQuestionID" foreign="id"/>
    </foreign-key>
    <vendor type="mysql">
        <parameter name="Engine" value="InnoDB"/>
    </vendor>
</table>

EDIT: Using join in place of joinWith did the job for me. Thanks @kripple.


Solution

  • You don't need a ->joinwith() to use ->useSurveyToSurveyQuestion()

    You can exclude the join calls resulting in the joined objects not being there.

    Additionally, I would have methods on each survey that got their respective questions and answers

    $surveys = SurveyQuery::create()->filterByXXX()->find()
    foreach($survey as $s){
      //Grab each survey's respective data
      $QandA = $s->getQuestionsAndAnswers();
      // do something with the data.
      $otherClass->doStuffWithData($QandA);
    }
    

    Doing so will increase trips to the DB no doubt, but I think the overall efficiency will be much better.