hasOne relation and Angular

37 views
Skip to first unread message

Jonathan Carlson

unread,
Feb 25, 2015, 10:18:14 AM2/25/15
to loopb...@googlegroups.com
Having a bit of trouble getting the hasOne relation working within Angular.

I'm building a survey app, with questions that can be reusable amongst surveys. I have two question models to represent this: SurveyQuestion and Question.

SurveyQuestion has a hasOne relation to Question
Question has two properties: text (the question text) and type (checkbox, radio button, text input, etc.)

Here's the JSON (removed parts that aren't applicable):

// SurveyQuestion Model
{
  "name": "SurveyQuestion",
  "plural": "surveyquestions",
  "base": "PersistedModel",
  "idInjection": true,
  "properties": {},
  "validations": [],
  "relations": {
    "question": {
      "type": "hasOne",
      "model": "Question",
      "foreignKey": "questionId"
    }
  },
  "acls": [],
  "methods": []
}


// Question Model
{
  "name": "Question",
  "plural": "questions",
  "base": "PersistedModel",
  "idInjection": true,
  "properties": {
    "text": {
      "type": "string",
      "required": true
    },
    "type": {
      "type": "string",
      "required": true
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": []
}



Here's my current solution for setting this up in Angular:

Survey.questions.create({ id: vm.survey.id }, {}).$promise.then(function(surveyQuestion) {
    console.log('survey question created!', surveyQuestion);

    SurveyQuestion.question.create({ id: surveyQuestion.id }, {
        text: 'What is your name?',
        type: 'text input'
    }).$promise.then(function(question) {
        console.log('question created!', question);
    });
});


The above does in fact create a SurveyQuestion instance and a Question instance, but both come back with a 'questionId' property which is actually the ID of the SurveyQuestion and not the Question.

Hope that wasn't too confusing, any ideas? Or better ideas for handling the Angular side?

Spencer Strombotne

unread,
Feb 25, 2015, 9:12:17 PM2/25/15
to
You're going to want to use a belongsTo relationship (SurveyQuestion belongsTo Question). By defining a belongsTo relationship, you're asserting that a SurveyQuestion cannot possibly exist without a Question. Doing this will put the questionId foreign key in your SurveyQuestion schema. 

A consequence of this is that you'll have to create the Question object prior to creating the SurveyQuestion object that belongs to it.
Question.create({...}).$promise.then(function(question){
   
SurveyQuestion.create({
        questionId
: question.id
   
}).$promise.then(function(surveyQuestion){
        surveyQuestion.question().$promise.then(...) //Get question for survey question
    });
});

Since you could have many SurveyQuestions that belongTo a Question, it's convenient to set up a hasMany relationship as well:

{
    "name": "Question",
    "plural": "questions",
    "base": "PersistedModel",
    "idInjection": true,
    "properties": {
        "text": {
            "type": "string",
            "required": true
        },
        "type": {
            "type": "string",
            "required": true
        }
    },
    "validations": [],
    "relations": {
        "surveyQuestions": {
            "type": "hasMany",
            "model": "SurveyQuestion",
            "foreignKey": "questionId" //Important to have same fk as the associated belongsTo relation
        }
    },
    "acls": [],
    "methods": []
}


Then you can create a new SurveyQuestion if you have access to an instance of a Question:
Question.create({...}).$promise.then(function(question){
    
question.surveyQuestions.create({...}).$promise.then(......);
});


Reply all
Reply to author
Forward
0 new messages