3

I am beginning with sails.js and I am completely lost with my sql queries.

I have the following tables :

genres
+-----------+--------------+------+-----+
| Field     | Type         | Null | Key |
+-----------+--------------+------+-----+
| id        | int(6)       | NO   | PRI | 
| name      | varchar(100) | NO   |     | 
| slug      | varchar(255) | NO   |     |
| type      | varchar(32)  | NO   |     | 
| parent_id | int(11)      | YES  | MUL | 
+-----------+--------------+------+-----+
genres_radios
+----------+--------+------+-----+
| Field    | Type   | Null | Key |
+----------+--------+------+-----+
| genre_id | int(6) | NO   | MUL |
| radio_id | int(6) | NO   | MUL |
+----------+--------+------+-----+
radios
+-----------+--------------+------+-----+
| Field     | Type         | Null | Key |
+-----------+--------------+------+-----+
| id        | int(5)       | NO   | PRI | 
| name      | varchar(100) | NO   |     | 
| slug      | varchar(100) | NO   |     |
| url       | varchar(100) | NO   |     | 
+-----------+--------------+------+-----+

I want to retrieve the radios and their associated genres. I managed to do it using the Model.query("Select * FROM ...") but I'd like to do it using the populate method. I had a look at the docs, but I am a bit confused with the "via", "through", ...

Mayur Shah
  • 3,344
  • 1
  • 22
  • 41
johnmalkovitch
  • 375
  • 1
  • 3
  • 9

2 Answers2

2

Well if you've followed the Sails.js Model documentation and the many-many association docs your models should look something like:

// api/models/genre.js
module.exports = {
    attributes : {
        name : {
            type: 'string'
        },
        slug : {
            type: 'string'
        },
        type : {
            type: 'string'
        },
        radios : {
            collection: 'radio',
            via: 'genres'
        }

    }
}

// api/models/radio.js
module.exports = {
    attributes : {
        name : {
            type: 'string'
        },
        slug : {
            type: 'string'
        },
        url : {
            type: 'string'
        },
        genres : {
            collection: 'genre',
            via: 'radios'
        }

    }
}

The many-many lookup table will be created for you internally by waterline. All you need to get the genres for your radio is populate the "genres" attribute.

Radio.findOne({name:"RadioName"}).populate("genres").then(function(radio){
    console.log(radio); //radio.genres will have all the genres associated with this radio. 
})

I really do recommend looking at the many-many association docs. They have exactly what you need.

Jason Kulatunga
  • 5,814
  • 1
  • 26
  • 50
  • I already did this, but on my result, the genres attribute is empty. Looking at what you wrote, I don't get how I'd be able to retrieve the genres of a radio when it's not told anywhere which genre_id it should look for (the radio_id an genre_id are stored in the genres_radios table) – johnmalkovitch Apr 03 '15 at 08:38
  • Ah, its a bit weird because you already have an existing table. Sails will actually create the genres_radios lookup table for you. – Jason Kulatunga Apr 07 '15 at 06:36
0

This should do it :

// api/models/Genres.js
module.exports = {
    attributes : {
        name : {
            type: 'string'
        },
        slug : {
            type: 'string'
        },
        type : {
            type: 'string'
        },
        radios : {
            collection: 'Radios',
            through: 'genres_radios'
        }
     }
}

// api/models/Radios.js
module.exports = {
    attributes : {
        name : {
            type: 'string'
        },
        slug : {
            type: 'string'
        },
        url : {
            type: 'string'
        },
        genres : {
            collection: 'genre',
            through: 'genres_radios'
        }
    }
}

// api/models/Genres_radios.js
module.exports = {
    attributes = {
        'Genre_id': {
            columnName:'genre_id',
            type:'integer',
            foreignKey:'true',
            references:'genres',
            on:'id',
            via:'genres'
        },
        'Radio_id': {
            columnName:'radio_id',
            type:'integer',
            foreignKey:'true',
            references:'radios',
            on:'id',
            via:'radios'
        }
    }
}

And then you can make the following request :

Radio.findOne({name:"RadioName"}).populate("genres").then(function(radio){
    console.log(radio); 
})
krakig
  • 1,515
  • 1
  • 19
  • 33