2014-10-07 62 views
7

Sails.js 0.10 RC8Sails.js同型号多对多关联

我已经完全用完的想法,这

我有一个模型叫用户,我想它的关联收集到其他用户,如朋友列表。像许多-to-many关联

//User.js 
    friends: { 
    collection: 'user', 
    via: 'friends' 
    } 

但是当我运行 .populate('friends') 它不填充任何内容。有任何想法吗?

+0

你有没有找到这个解决方案?我目前正在尝试做同样的事情。 – Michael 2015-02-23 04:47:19

+1

嗨迈克尔,这是问题,因为它是相同的模型,这意味着他们都有一个多对多的关联。水线自动创建连接表,但它占据了主导地位。所以你不能使用它的填充函数。我发现的最好方法是创建另一个模型(例如Friends.js),并创建一个用户模型,然后创建其他用户模型集合。然后,我设置了一个“填充”的钩子,当我需要它时。 – scott 2015-02-23 15:12:11

+1

谢谢斯科特!这正是我要去的地方,但很高兴听到它真的为你工作。我会继续朝着这条道路前进。 – Michael 2015-02-24 03:23:52

回答

1

我发现实现这个最好的方法实际上是增加了对id的引用。

检查这个用户模型:

module.exports = { 
    attributes: { 
    name: { 
     type: 'string', 
     required: true, 
     minLength: 2 
    }, 
    email: { 
     type: 'email', 
     required: true, 
     unique: true 
    }, 
    friends: { 
     collection: 'user', 
     via: 'id' 
    } 
    } 
}; 

现在,如果你运行sails console您可以测试下面的命令:

User.create({name:'test',email:'[email protected]'}).exec(console.log); 

它返回:

{ name: 'test', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:06:19.723Z', 
    updatedAt: '2016-12-01T22:06:19.723Z', 
    id: 1 } 

您创建了第一个用户。让我们创建一些其他的:

User.create({name:'test2',email:'[email protected]'}).exec(console.log); 

结果造成:

{ name: 'test2', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:06:40.808Z', 
    updatedAt: '2016-12-01T22:06:40.808Z', 
    id: 2 } 

让我们看看我们至今:

User.find().populate('friends').exec(console.log); 

[ { friends: [], 
    name: 'test', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:06:19.723Z', 
    updatedAt: '2016-12-01T22:06:19.723Z', 
    id: 1 }, 
    { friends: [], 
    name: 'test2', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:06:40.808Z', 
    updatedAt: '2016-12-01T22:06:40.808Z', 
    id: 2 } ] 

现在,让我们创建一个用户与朋友,使用引用第一个用户。请注意,我只传递一个ID,而不是数组:

User.create({name:'test3',email:'[email protected]', friends:1}).exec(console.log); 

现在,结果是这一个。请注意,“朋友”没有出现。这是设计。

{ name: 'test3', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:07:34.988Z', 
    updatedAt: '2016-12-01T22:07:34.994Z', 
    id: 3 } 

让我们做一个找到populate查看当前状态:

User.find().populate('friends').exec(console.log); 

现在我们看到的是,第三用户朋友。其他人有一个空阵列。

[ { friends: [], 
    name: 'test', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:06:19.723Z', 
    updatedAt: '2016-12-01T22:06:19.723Z', 
    id: 1 }, 
    { friends: [], 
    name: 'test2', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:06:40.808Z', 
    updatedAt: '2016-12-01T22:06:40.808Z', 
    id: 2 }, 
    { friends: 
    [ { name: 'test', 
     email: '[email protected]', 
     createdAt: '2016-12-01T22:06:19.723Z', 
     updatedAt: '2016-12-01T22:06:19.723Z', 
     id: 1 } ], 
    name: 'test3', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:07:34.988Z', 
    updatedAt: '2016-12-01T22:07:34.994Z', 
    id: 3 } ] 

让我们创建一个第四名,这时候有两个朋友:

User.create({name:'test4',email:'[email protected]', friends:[1,2]}).exec(console.log); 

,导致(再次,没有朋友属性):

{ name: 'test4', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:07:50.539Z', 
    updatedAt: '2016-12-01T22:07:50.542Z', 
    id: 4 } 

这一次,我们通过一个数组的ID为friends。让我们看看目前的状态:

​​

现在,你如何添加一个朋友到现有的用户?这有点奇怪:你必须先用find这个用户,然后在产生的模型上用add函数,然后,save它。在我的日常代码中,我有一个辅助函数可以做到这一点。因此,下面是示例:

User.findOne(1).populate('friends').exec(function(err,u){ u.friends.add(3);u.save(function(err){ if(err) console.error(err);});}); 

现在在控制台中我们看不到任何结果。 现在让我们来检查用户内容:

User.find().populate('friends').exec(console.log); 

[ { friends: 
    [ { name: 'test3', 
     email: '[email protected]', 
     createdAt: '2016-12-01T22:07:34.988Z', 
     updatedAt: '2016-12-01T22:07:34.994Z', 
     id: 3 } ], 
    name: 'test', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:06:19.723Z', 
    updatedAt: '2016-12-01T22:09:41.410Z', 
    id: 1 }, 
    { friends: [], 
    name: 'test2', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:06:40.808Z', 
    updatedAt: '2016-12-01T22:06:40.808Z', 
    id: 2 }, 
    { friends: 
    [ { name: 'test', 
     email: '[email protected]', 
     createdAt: '2016-12-01T22:06:19.723Z', 
     updatedAt: '2016-12-01T22:09:41.410Z', 
     id: 1 } ], 
    name: 'test3', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:07:34.988Z', 
    updatedAt: '2016-12-01T22:07:34.994Z', 
    id: 3 }, 
    { friends: 
    [ { name: 'test', 
     email: '[email protected]', 
     createdAt: '2016-12-01T22:06:19.723Z', 
     updatedAt: '2016-12-01T22:09:41.410Z', 
     id: 1 }, 
     { name: 'test2', 
     email: '[email protected]', 
     createdAt: '2016-12-01T22:06:40.808Z', 
     updatedAt: '2016-12-01T22:06:40.808Z', 
     id: 2 } ], 
    name: 'test4', 
    email: '[email protected]', 
    createdAt: '2016-12-01T22:07:50.539Z', 
    updatedAt: '2016-12-01T22:07:50.542Z', 
    id: 4 } ] 

使用这种方法,您可以在同一用户甚至添加到友人收藏!

User.findOne(1).populate('friends').exec(function(err,u){ u.friends.add(1);u.save(function(err){ if(err) console.error(err);});}); 

玩得开心!

0

您应该使用的.populate('friends')代替.populate(friends)

+0

我真的很感激你的回复。当我的意思是.populate('朋友'),但它不起作用:-( – scott 2014-10-08 04:46:42

+1

@scott试试看:收集:'用户', – haotang 2014-10-08 07:33:58

2

你的模型应该是这样的......

//User.js 
friends: { 
    collection: 'friend', 
    via: 'user' 
} 

//Friend.js 
user: { 
    model: 'user' 
    via: 'friends' 
} 

而且航行10 RC8是旧的。你应该在航行10.5

0

事实证明,当你在水线上有多对多的关联时,你必须声明其中一个模型为主导。由于它们是相同的模型,所以都不占主导地位。在创建连接表时,无法填充它。

+0

Dominant用于跨适配器查询,而不是你描述的。http: //sailsjs.com/documentation/concepts/models-and-orm/associations/dominance它只是说帮助程序表将在何处创建 – 2016-12-01 01:03:27

+0

当您在多对多关联中设置主导权时,您是正确的,它确实会说其中连接表将在发生跨适配器查询时发生,但它也会影响连接表的命名顺序正常情况'user_friends__friend_users'这些名称很重要,因为它们将是模型的名称和属性。 ,这些不能在同一个模型中(参见OP注释)。因为水线错误,连接表出错了。如果我回想起来,连接表名称以user_friends__users_friends或类似'user'这个表的名称出现不存在。 – scott 2016-12-01 18:41:06