От другия ви въпрос разбрах, че една задача може да принадлежи на много служители, нали? Така че трябва да използвате belongsToMany
връзка във вашата Task
модел. Също така вашата примерна колекция от „задачи“ показва, че в един документ employee_id
е масив, а в другия документ е ObjectId, когато и двете трябва да са масиви.
Както и да е, трудно се опитах да разбера това, но видях, че не можете да използвате hasMany
като обратното на belongsToMany
, защото belongsToMany
създава масив от идентификатори и hasMany
не работи добре с масиви. Бих казал, че ще ни трябва нещо като hasManyInArray
, но когато асоциирам belongsToMany
връзка, документът "родител" се създава масив от идентификатори, което ме кара да мисля, че родителят също трябва да използва belongsToMany
въпреки че не „принадлежи на“, а всъщност „има“. Така че, когато свържете служител със задача като тази:
$task->employees()->save($employee);
Документът "служител" в крайна сметка ще има атрибут "task_ids" с единствения идентификатор на задача, който трябва да има. Така че изглежда това е начинът да вървим с Jenssegers:да използваме belongsToMany
и в двата модела:
Laravel:Модел:Служител:
<?php
namespace App\Models;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Employee extends Eloquent
{
protected $collection = 'employee';
public function tasks()
{
return $this->belongsToMany(Task::class);
}
}
Laravel:Модел:Задача:
<?php
namespace App\Models;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Task extends Eloquent
{
protected $collection = 'task';
public function employees()
{
return $this->belongsToMany(Employee::class);
}
}
И бихте използвали това като:
// Give a task a new employee
$task->employees()->save($employee);
// Or give an employee a new task
$employee->tasks()->save($task);
Единственото нещо в това е, че когато погледнете базата данни, ще видите, че документите на вашите служители имат масив, наречен „task_ids“, а вътре в него идентификаторът на единствената задача, която всеки служител има. Надявам се, че това помогна.
Само някои странични бележки, знаете, че не е нужно да дефинирате името на първичния ключ на всеки модел, нали? Нямате нужда от това:
protected $primaryKey = '_id';
Също така не е необходимо да дефинирате името на колекцията (т.е. protected $collection = 'employee';
), освен ако наистина не искате да са в единствено число (по подразбиране са в множествено).
Станах посред нощ (тук е 3:52 ч. сутринта) и проверих нещо на компютъра и след това проверих, така че видях въпроса ви, надявам се този път да ви отговоря достатъчно скоро, изглежда сме в различни часови зони.
Това са документите, които създадох за тестване:
събиране на служители
{
"_id" : ObjectId("5870ba1973b55b03d913ba54"),
"name" : "Jon",
"updated_at" : ISODate("2017-01-07T09:51:21.316Z"),
"created_at" : ISODate("2017-01-07T09:51:21.316Z"),
"task_ids" : [
"5870ba1973b55b03d913ba56"
]
},
{
"_id" : ObjectId("5870ba1973b55b03d913ba55"),
"name" : "Doe",
"updated_at" : ISODate("2017-01-07T09:51:21.317Z"),
"created_at" : ISODate("2017-01-07T09:51:21.317Z"),
"task_ids" : [
"5870ba1973b55b03d913ba56"
]
}
колекция от задачи
{
"_id" : ObjectId("5870ba1973b55b03d913ba56"),
"name" : "New Task",
"updated_at" : ISODate("2017-01-07T09:51:21.317Z"),
"created_at" : ISODate("2017-01-07T09:51:21.317Z"),
"employee_ids" : [
"5870ba1973b55b03d913ba54",
"5870ba1973b55b03d913ba55"
]
}
С тези документи получавам първия служител така:
$employee = Employee::with('tasks')->first();
dd($employee);
И в изхода можем да видим, че атрибутът на релациите е масив:
Employee {#186 ▼
#collection: "employee"
#primaryKey: "_id"
// Etc.....
#relations: array:1 [▼
"tasks" => Collection {#199 ▼
#items: array:1 [▼
0 => Task {#198 ▼
#collection: "task"
#primaryKey: "_id"
// Etc....
#attributes: array:5 [▼
"_id" => ObjectID {#193}
"name" => "New Task"
"updated_at" => UTCDateTime {#195}
"created_at" => UTCDateTime {#197}
"employee_ids" => array:2 [▶]
]
}
]
}
]
}
belongsToMany
методът не е във файла, който споменавате, защото този клас (т.е. Jenssegers\Mongodb\Eloquent\Model
) разширява класа Eloquent Model на Laravel и това е мястото, където belongsToMany
метод е.
Добре, така че това трябва да е причината, поради която не работи за вас, защото масивите трябва да бъдат низове вместо ObjectIds. Защо е това? Тъй като библиотеката на Jenssegers работи така, тя записва идентификаторите като низове. Също така намирам това поведение за странно, но така работи. Не забравяйте, че се предполага за свързване на обекти с помощта на библиотеката на Jenssegers, а не чрез създаване на данните ръчно в базата данни. Как можете да индексирате идентификаторите? Просто създайте нормален индекс в MongoDB, като tasks.createIndex({task_ids: 1})
. Ето документацията за създаване на индекси:https://docs .mongodb.com/manual/reference/method/db.collection.createIndex/
. Можете също да създавате индекси за миграции, ето документите за миграции
, не забравяйте да прочетете бележките на Jenssegers относно миграциите
също.
Имате достъп до tasks
реалност като тази:$employee->tasks;
. Вие осъществявате достъп до релации, като получите свойство със същото име на метода, с който сте декларирали релацията си, така че ако имате:
class Post
{
public function owner()
{
return $this->belongsTo(User::class);
}
}
Получавате релацията като $post->owner;
. Ето документацията за отношенията:https://laravel.com/docs/5.3/eloquent-relationships