Ho capito dall'altra tua domanda, che un compito può appartenere a molti dipendenti, giusto? Quindi dovresti usare belongsToMany
relazione nella tua Task
modello. Anche la tua raccolta di "attività" di esempio mostra che in un documento employee_id
è un array e nell'altro documento è un ObjectId, quando entrambi dovrebbero essere array.
Ad ogni modo, ho avuto difficoltà a cercare di capirlo, ma ho visto che non puoi usare hasMany
come l'inverso di belongsToMany
, perché belongsToMany
crea una matrice di ID e hasMany
non funziona bene con gli array. Direi che avremmo bisogno di qualcosa come hasManyInArray
, ma quando associo un belongsToMany
relazione, il documento "genitore" viene creato un array di ID, il che mi porta a pensare che anche il genitore dovrebbe usare belongsToMany
anche se non "appartiene" ma in realtà "ha". Quindi, quando assoceresti un dipendente a un'attività come questa:
$task->employees()->save($employee);
Il documento "employee" finirà per avere un attributo "task_ids" con l'unico ID attività che dovrebbe avere. Quindi questa sembra essere la strada da percorrere con Jenssegers:usare belongsToMany
in entrambi i modelli:
Laravel:Modello:Impiegato:
<?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:Modello:Compito:
<?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);
}
}
E useresti questo come:
// Give a task a new employee
$task->employees()->save($employee);
// Or give an employee a new task
$employee->tasks()->save($task);
L'unica cosa è che quando guardi il database, vedrai che i documenti dei tuoi dipendenti hanno un array chiamato "task_ids" e al suo interno, l'id dell'unica attività che ogni dipendente ha. Spero che questo ha aiutato.
Solo alcune note a margine, sai che non devi definire il nome della chiave primaria su ogni modello, giusto? Non hai bisogno di questo:
protected $primaryKey = '_id';
Inoltre non è necessario definire il nome della collezione (es. protected $collection = 'employee';
), a meno che tu non voglia davvero che siano al singolare (per impostazione predefinita sono al plurale).
Mi sono alzato nel cuore della notte (sono le 3:52 qui) e ho controllato qualcosa sul computer e poi ho controllato SO e ho visto la tua domanda, spero che questa volta abbia risposto abbastanza presto per te, sembra che siamo in fusi orari diversi.
Questi sono i documenti che ho creato per il test:
raccolta dipendenti
{
"_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"
]
}
raccolta attività
{
"_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"
]
}
Con questi documenti ottengo il primo dipendente così:
$employee = Employee::with('tasks')->first();
dd($employee);
E nell'output possiamo vedere che l'attributo delle relazioni è un array:
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 [▶]
]
}
]
}
]
}
Il belongsToMany
il metodo non è nel file che menzioni perché quella classe (cioè Jenssegers\Mongodb\Eloquent\Model
) estende la classe Eloquent Model di Laravel, ed è qui che belongsToMany
metodo è.
Ok, questo deve essere il motivo per cui non funziona per te, perché gli array devono essere stringhe anziché ObjectIds. Perchè è questo? Perché è così che funziona la libreria Jenssegers, salva gli ID come stringhe. Ho anche trovato strano questo comportamento, ma è così che funziona. Ricorda che dovresti per mettere in relazione gli oggetti usando la libreria Jenssegers, non creando i dati manualmente nel database. Come puoi indicizzare gli ID? Basta creare un indice normale in MongoDB, come tasks.createIndex({task_ids: 1})
. Ecco la documentazione su come creare indici:https://docs .mongodb.com/manual/reference/method/db.collection.createIndex/
. Puoi anche creare indici sulle migrazioni, ecco i documenti sulle migrazioni
, assicurati di leggere le Note Jenssegers sulle migrazioni
anche.
Puoi accedere alle Task
realtion in questo modo:$employee->tasks;
. Accedi alle relazioni ottenendo una proprietà con lo stesso nome del metodo con cui hai dichiarato la tua relazione, quindi se hai:
class Post
{
public function owner()
{
return $this->belongsTo(User::class);
}
}
Ottieni la relazione come $post->owner;
. Ecco la documentazione sulle relazioni:https://laravel.com/docs/5.3/eloquent-relationships