本文介绍了我对 Sails.js 水线一对一关联逻辑感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我很困惑,因为我是一名 PHP 开发人员,并且经常使用 Laravel 和 FuelPHP

So the reason why im confused, because I am a PHP developer and used Laravel and FuelPHP alot

我真正不明白的是它本身的关联.

What i dont really understand is the association it self.

我的意思是,我想创建一个基本的 hasOne/BelongsTo 逻辑,如下

What i mean, i wanted to create a basic hasOne / BelongsTo logic, with the following

用户有一个个人资料

个人资料属于用户

我习惯了下面的搭建(Laravel 风格)

I am used to the following build up (Laravel style)

用户表

id | username    | email     | password
---------------------------------------
1  | My Username | My email  | 1234568

Users_profile 表

user_id | first_name    | last_name
----------------------------------------
1       | My First name | My Last name

然后我就这样定义了模型

Then i just defined models this way

用户模型

class Users extends Eloquent
{
    public function profile()
    {
        return $this->hasOne('profile');
    }
}

配置文件模型

class Profile extends Eloquent
{
    protected $tableName = 'users_profile';

    protected $primaryKey = 'user_id';

    public function user()
    {
        return $this->belongsTo('User');
    }
}

它只是有效,因为 return $this->hasOne('profile'); 将自动检查 user_id

And it just works, because the return $this->hasOne('profile'); will auto check for the user_id

在 Sails.js 中尝试了相同的方法(以帆的方式)

Tried the same in Sails.js (in the sails way)

用户模型

module.exports = {

  attributes: {

    username: {
        type: 'string',
        unique: true,
        required: true
    },

    email: {
        type: 'string',
        unique: true,
        email: true,
        required: true
    },

    password: {
        type: 'string',
        required: true
    },

    profile: {
      model: "profile",
    }

  },
};

配置文件模型

module.exports = {

    tableName: 'user_profile',

    autoPK: false,

    autoCreatedAt: false,

    autoUpdateddAt: false,

  attributes: {

    user_id: {
        type: 'integer',
        primaryKey: true
    },

    first_name: {
        type: 'string',

    },

    last_name: {
        type: 'string',

    },

    user: {
      model: "user"
    }

  }
};

现在从文档中阅读我必须以这种方式更新我的表格

And reading from the documentation now i have to update my table this way

id | username    | email     | password | profile
-------------------------------------------------
1  | My Username | My email  | 1234568  | 1



user_id | first_name    | last_name    | user |
-----------------------------------------------
1       | My First name | My Last name |  1

所以我需要再次存储 2 个 ID,但我真的不明白为什么.

So i need to store 2 more id's again, and i do not really get why.

比我进一步阅读尝试使用 via 没有用(注意是用于集合)

Than i read further tried to use via did not work (noted that is for collections)

那么,谁能给我一个 Laravelis 风格的逻辑示例?

So, anybody could give me a logic example for a Laravelis style?

在文档中对此一无所知(更简单的方法),因为在我看来,如果用户拥有更多关系,这将导致 ID 地狱(只是我的观点)

Foud nothing about this in the docs (a more easier way), because in my opinion if the user will have more relations, this will cause and ID hell (just my aopinion)

推荐答案

这是一个 已知问题 Sails 不完全支持一对一关联;您必须在您希望能够填充的任何一侧设置外键.也就是说,如果您想让 User #1 链接到 Profile #1 并且能够执行 User.find(1).populate('profile'),您将设置 User #1 的 profile 属性,但这并不意味着会自动执行 Profile.find(1).populate('user') 将起作用.这与 Sails 中的多对多关系相反,其中在一侧添加链接就足够了.这是因为 to-many 关系使用连接表,而 to-one 关系不使用.

It is a known issue that Sails doesn't fully support one-to-one associations; you have to set the foreign key on whichever side you want to be able to populate from. That is, if you want to have User #1 linked to Profile #1 and be able to do User.find(1).populate('profile'), you would set the profile attribute of User #1, but that doesn't automatically mean that doing Profile.find(1).populate('user') will work. This is as opposed to many-to-many relationships in Sails, where adding the link on one side is sufficient. That's because to-many relationships use a join table, whereas to-one relationships do not.

这在 Sails 中没有成为优先事项的原因是一对一的关系通常不是很有用.除非您有非常令人信服的理由不这样做,否则最好将两个模型合并为一个.

The reason this hasn't been a priority in Sails is that one-to-one relationships are usually not really useful. Unless you have a really compelling reason for not doing so, you're better off just merging the two models into one.

无论如何,如果你真的需要它,你可以使用.afterCreate 生命周期回调 以确保双向链接,例如在 User.js 中:

In any case, if it's something you really need, you can use the .afterCreate lifecycle callback to ensure a bi-directional link, for example in User.js:

module.exports = {

  attributes: {...},

  afterCreate: function(values, cb) {

    // If a profile ID was specified, or a profile was created
    // along with the user...
    if (values.profile) {
      // Update the profile in question with the user's ID
      return Profile.update({id: values.profile}, {user: values.id}).exec(cb);
    }

    // Otherwise just return
    return cb();
  }
};

您可以将类似的 .afterCreate() 添加到 Profile.js 以在创建配置文件时处理更新受影响的用户.

You could add a similar .afterCreate() to Profile.js to handle updating the affected user when a profile was created.

这篇关于我对 Sails.js 水线一对一关联逻辑感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 09:01