Меня смущает логика взаимно однозначной связи водной линии Sails.js

Итак, причина, по которой я запутался, потому что я 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 идентификатора, и я действительно не понимаю, почему.

Чем я читал дальше, пытался использовать via, не получилось (отметил, что для коллекций)

Итак, кто-нибудь может привести мне логический пример для стиля Lavelis?

Ничего не нашел об этом в документах (более простой способ), потому что, на мой взгляд, если у пользователя будет больше отношений, это вызовет и ID ад (только мое мнение)


person Community    schedule 02.01.2015    source источник


Ответы (1)


Это известная проблема, которую Sails не полностью поддерживает. однозначные ассоциации; вы должны установить внешний ключ на той стороне, с которой вы хотите иметь возможность заполнять. То есть, если вы хотите связать User #1 с Profile #1 и иметь возможность выполнять User.find(1).populate('profile'), вы должны установить атрибут profile для User #1, но это не означает автоматически, что выполнение Profile.find(1).populate('user') будет работать. Это отличается от отношений многие ко многим в Sails, где достаточно добавить ссылку с одной стороны. Это связано с тем, что отношения ко многим используют таблицу соединения, а отношения к одному — нет.

Причина, по которой это не было приоритетом в Sails, заключается в том, что отношения «один к одному» обычно не очень полезны. Если у вас нет действительно веской причины этого не делать, лучше просто объединить две модели в одну.

В любом случае, если вам это действительно нужно, вы можете использовать обратный вызов жизненного цикла .afterCreate. для обеспечения двунаправленной связи, например, в 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 для обработки обновления затронутого пользователя при создании профиля.

person sgress454    schedule 03.01.2015
comment
Не знал об этой проблеме. И спасибо за наводку и за развернутый ответ - person ; 03.01.2015
comment
Тоже не понимал, что это проблема. Вы бы подумали, что это стоит упомянуть в документах... - person youngrrrr; 09.03.2016
comment
Теперь в документах есть целая страница посвященный этому. - person sgress454; 15.03.2016