我对Sails.js水线一对一关联逻辑感到困惑

时间:2015-01-02 15:06:09

标签: node.js orm associations sails.js waterline

所以我之所以感到困惑,是因为我是一名PHP开发人员并且使用过Laravel和FuelPHP很多

我真正理解的是它自己的关联。

我的意思是,我想创建一个基本的hasOne / BelongsTo逻辑,具有以下内容

用户有一个个人资料

个人资料属于用户

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

用户表

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  

然后我就这样定义了模型

用户模型

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

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

用户模型

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"
    }

  }
};

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

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,我真的不明白为什么。

比我读更进一步尝试使用via不起作用(注意到收集)

那么,任何人都可以给我一个Laravelis风格的逻辑例子吗?

在文档中没有任何相关内容(更简单的方法),因为在我看来,如果用户会有更多的关系,这将导致ID地狱(只是我的aopinion)

1 个答案:

答案 0 :(得分:8)

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

这在Sails中不是优先考虑的原因是一对一关系通常不是很有用。除非你有really compelling reason没有这样做,否则你最好将两个模型合并为一个。

在任何情况下,如果这是您真正需要的,您可以使用.afterCreate lifecycle callback来确保双向链接,例如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,以便在创建个人资料时更新受影响的用户。