0

I'm quite new to the Sails.js (and node) scene.

Currently i'm creating an app in which users can create blogposts and view them afterwards. It all went well retrieving the posts on the index page, although i'm running into trouble when i'm trying to show the name of the author.

To achieve this I've made two models: Posts and Users. When a Posts gets created, I add a 'postedBy' attribute to the Post model, containing the id of the user to which the post belongs.

Now, In my index view (where i'm showing posts) i'm doing something like this:

<% _.each(posts, function(post) { %>
    <a href="/post/show/<%= post.id %>">
        <div class="post" data-id="<%= post.id %>" data-model="post">
            <div class="row panel-body">
                <div class="col-xs-7">
                    <h3><%= post.title %></h3>
                    <span class="date">By <%= post.postedBy %> <span class="date-nicely"><%= post.createdAt %></span></span>
                </div>
                <div class="col-xs-4">
                    <!-- Other markup -->
                </div>
            </div>
        </div>
    </a>
<% }); %>

Everything in here works properly. Although I want to access the User's data by searching for it using the 'postedBy' attribute, so I can display their name and maybe other stuff. I don't want to store the poster's name directly into the Post model, because usernames will be subject to change, and should be linked directly to the User name.

'index': function(req, res, next) {
    var customerID = req.session.User.customerID;

    Post.find()
        .where({ customerID: customerID })
        .limit(5)
        .sort('createdAt DESC')
        .done( function foundPosts(err, posts) {
            if ( err ) {
              return next(err);
            }
            res.view({
              posts: posts,
              layout: req.session.layout
            });
        }
    );
},

In my controller I've tried to loop through the posts I obtained from MongoDB (by using Post.find().limit(5).sort('createdAt DESC').done(function(err, posts){}); - Something like this). I've read about Promised in the Sail.js / waterline documentation, although I somehow can't get it to work so that I can access the specific User within each Post loop.

Travis Webb
  • 14,688
  • 7
  • 55
  • 109
Lars Dol
  • 765
  • 1
  • 6
  • 14

1 Answers1

1

To get this to work, you have two alternatives:

Using Sails.js version 0.9

You have to nest the queries. Take a look at this example:

In your .done() function:

.done(function foundPosts(err, posts) {

    posts.forEach(function(post){
        User.find().where({ owner: post.ownerID }).done(function (err, user) {
            // create new property on the post object
            post.user = user.ownerName;
        });
    });

    res.view({
      posts: posts,
      layout: req.session.layout
    });
}

Using Sails.js version 0.10

In the (currently) latest version of sails.js you have associations. That means you can model the association in you model schema. Example:

// From the file: myApp/api/models/posts.js

module.exports = {

    attributes: {
        title:'STRING',
        body:'STRING',
        author:{
            model: 'user' // Here you associate the user model
        }
    }

}

That means, in your query, you could do something like this:

Post.find().where({ customerID: customerID }).populate('user').exec(function(err, posts){
    res.view({
      posts: posts,
      layout: req.session.layout
    });
});
aludvigsen
  • 5,893
  • 3
  • 26
  • 37
  • Hi, thanks for the reply! - I've updated to 0.10, although I can't seem to figure out how the get the associations to work. I've tried Post.find().where({ customerID: customerID }).populate('author').exec(function(err, posts){ res.view({ posts: posts, layout: req.session.layout }); }); The first time I post something everything works, although the second post will redirect to my post/new template.. And stop working. Also, how exactly does the Post know to which user it belongs? Where does it get connected? – Lars Dol Apr 28 '14 at 17:15
  • Without knowing how your `model` looks, it's difficult to answer. I suggest you do this, first; read about associations in the sails docs. If you cannot find out why it's not working as you expect, create another question here on SO, and I will help you :) – aludvigsen Apr 28 '14 at 20:07
  • 1
    It had to do with the fact that I was getting my params by calling var params = req.params.all(). This mixed in some random ID that confused waterline / sails-mongo. When I replaced it by var params = req.body, everything worked as intended :). – Lars Dol May 01 '14 at 07:48