I am confused with Sails.js waterline one-to-one association logic

断了今生、忘了曾经 提交于 2019-12-03 20:27:00

问题


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.

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

User has one profile

Profile belongs to an user

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

Users table

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

Users_profile table

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

Then i just defined models this way

User model

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

Profile model

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

    protected $primaryKey = 'user_id';

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

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

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

User model

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

  },
};

Profile model

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

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

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

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

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)


回答1:


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.

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.

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();
  }
};

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



来源:https://stackoverflow.com/questions/27744179/i-am-confused-with-sails-js-waterline-one-to-one-association-logic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!