Undertand how to use relationships

Hello,
I have some troubles to understand how I can make a relationship between schemas.
I use simple-schema to manage my models and I currently have:

  • an intervention model
  • a customer model.

Each intervention is linked to a customer.

This is what I did:

Schemas.Intervention = new SimpleSchema({
[…]
customer: {
type: String,
}
});

My template render a select:

    {{> afQuickField name="customer" options=customers}}

where customers are passed:

Template.addIntervention.helpers({
customers: function () {
return Customers.find().map(function © {
return {label: c.name, value: c._id};
});
}
});

My point is, how to store the customer object instead of the string (which in fact contains the customer _id).

I’ve tried:

Schemas.Intervention = new SimpleSchema({
[…]
customer: {
type: Schema.customer,
}
});

but with, I loose my select in my template.

You don’t need to attach a schema if you want to generate a dropdown list from other collections, you may edit your intervention schema like this:

Intervention.attachSchema( new SimpleSchema({
  customer: {
    type: String
  } 
 })
);

your Customer schema:

Customers.attachSchema( new SimpleSchema({
  name: {
    type: String
  }
}))

your helpers:

Template.addIntervention.helpers({
  customers: function () {
    return Customers.find().map(function (c) {
      return {label: c.name, value: c._id};
      });
    }
});

on your addIntervention form template:

{{> afQuickField name="customer" options=customers }} // from addIntervention helpers

That’s it. The select(dropdown) list will generate since you map the field name on Customers collection.

Or if you want detailed explanation you may want to read the new awesome Meteor Guide, though, the relationship there is not explicitly say the term relationship, it has a different approach with the use of collection helpers.

Hope this helps.

Thanks for replying but in my interventions list i’d like to have to customer name instead of the _id and I don’t know ho to do.

Make sure that you are subscribed to Customers collection on your addIntervention template.

Are you using template level subscription or route subscription?

I do not understand your question but I think you’ll find the answer in the repo
(autopublish is not yet deactivated)

Since, autopublish is not yet deactivated, you should see all the data from other collections.

I suggest try to deactivate autopublish and insecure and set up your publication and subscription.

Here’s how you do it:
/server/publication.js

Meteor.publish('customer', function(){ // 'customer' is the name of your publication
  return Customers.find();
});

Meteor.publish('intervention', function(){ // same here 'intervention' is your publication name
  return Interventions.find();
});

/client/add_intervention.js

Template.addIntervention.onCreated( function() {
  this.subscribe('intervention'); // from intervention publication
  this.subscribe('customer'); // from customer publication
});

on your addIntervention template:

<template name="addIntervention">
  {{#if Template.subscriptionsReady}} // template level subscription
	{{#autoForm collection="Interventions" id="addInterventionForm" type="insert"}}
	    {{> afQuickField name="title"}}
	    {{> afQuickField name="priority" options="allowed"}}	    
	    {{> afQuickField name="customer" options=customers}}
	    <button type="submit" class="btn btn-primary">Submit</button>
  	{{/autoForm}}
  {{/if}}
</template>

You should see the name of the customers on the dropdown list instead of their id’s since you already subscribed to Customers collection.

You can do the template subscription on your other template. Try to read the Meteor Guide for further learning.

You should also read this security topic on Meteor Guide regarding the allow/deny rules on your collections.

I agree with you and the autosubscribe but I do not understand how it way change the situation.
How can I see the customer name insted of his _id in:

{{#each interventions}}
    {{title}}
    {{customer}}    
{{/each}}

You should create a helpers like this:

Template.interventions.helpers({
  customerName: function (name) {
    var Name = Customers.findOne( name );
    if ( Name ) {
      return Name.name;
    }
  }
});

on your template:

{{#each interventions}}
    {{title}}
    {{customerName customer}}    
{{/each}}

You can see the name of each customer.

Thanks for the Helper, this is a nice trick.
I thought I could set a relationship between my 2 schema and access properties like {{customer.name}}, {{customer.addresse.city}} etc. like here

The process describe there is not exactly a relationship, it’s the way you attach a schema from other collection, the output describe there is generating the input control from other schema not the data itself.

You can tinker a little bit to accomplish the way you want it, I too have issues, I’m far from a meteor expert.

Does this solve your issue?

hum yes, “attach a schema from other collection” is maybe the correct asking.
Your trick does not solve my issue, I have to find another.