Alguém pode me ajudar em como salvar muitos relacionamentos? Eu tenho tarefas, o usuário pode ter muitas tarefas e a tarefa pode ter muitos usuários (muitos para muitos). O que eu quero alcançar é que no formulário de atualização o administrador possa atribuir vários usuários a uma tarefa específica. Isso é feito por meio de entrada de seleção múltipla html
name="taskParticipants[]"
O problema aqui é que através do mesmo formulário (entrada) você pode adicionar / remover usuários, por isso tenho que usar o sync (). Talvez eu deva começar do início, mas não sei por onde começar ...
Este é o meu modelo de usuário:
public function tasks()
{
return $this->belongsToMany('Task','user_tasks');
}
Modelo de tarefa
public function taskParticipants()
{
return $this->belongsToMany('User','user_tasks');
}
TaskController
public function update($task_id)
{
if (Input::has('taskParticipants'))
{
foreach(Input::get('taskParticipants') as $worker)
{
$task2 = $task->taskParticipants->toArray();
$task2 = array_add($task2,$task_id,$worker);
$task->taskParticipants()->sync(array($task2));
}
}
}
Esta é a estrutura das tarefas de tabelas id | título | prazo
user_tasks
id|task_id|user_id
laravel
laravel-4
eloquent
relationship
SuperManSL
fonte
fonte
$workers = Input::get('taskParticipants'); $task->taskParticipants()->sync($workers);
e isso é tudo que você precisa, desde que passe daquele formulário todos os usuários atribuídos à tarefa.Respostas:
tldr; Use
sync
com o 2º parâmetrofalse
O relacionamento muitos para muitos ocorre
belongsToMany
em ambos os modelos:// Task model public function users() { return $this->belongsToMany('User', 'user_tasks'); // assuming user_id and task_id as fk } // User model public function tasks() { return $this->belongsToMany('Task', 'user_tasks'); }
Para adicionar uma nova relação, use
attach
ousync
.A diferença entre os dois é:
1
attach
adicionará uma nova linha na tabela dinâmica sem verificar se ela já está lá. É bom quando você tem dados adicionais vinculados a essa relação, por exemplo:User
eExam
vinculado à tabela dinâmicaattempts: id, user_id, exam_id, score
Suponho que não seja isso que você precisa na sua situação:
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6] $user->tasks()->attach([5,6,7]); // then $user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,5,6,7]
2
sync
por outro lado, irá remover todas as relações e configurá-las novamente:$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6] $user->tasks()->sync([1,2,3]); // then $user->tasks()->getRelatedIds(); // [1,2,3]
ou irá configurar novas relações sem separar o E anterior sem adicionar duplicatas:
$user->tasks()->sync([5,6,7,8], false); // 2nd param = detach // then $user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,7,8]
fonte
$this->belongsToMany('User')
se usar o nome da tabela em ordem alfabética e singular (emtask_user
vez deuser_tasks
)sync
com desanexação, não se preocupe. Eu sugiro usar o segundo parâmetro definido como falso sempre que quiser 'adicionar nova tarefa para um usuário' ou 'atribuir usuário a uma tarefa', quando você passar umid
dos modelos relacionados.sync
retorna uma matriz comdetached
,attached
eupdated
listas.attach
não retorna nada, mas em ambos os casos você obteria uma exceção se algo inesperado acontecesse nas chamadas de banco de dados.Aqui estão minhas notas sobre como salvar e atualizar todos os relacionamentos do Eloquent.
em um para um :
Você deve usar HasOne no primeiro modelo e BelongsTo no segundo modelo
para adicionar registro no primeiro modelo ( HasOne ) use a função salvar
exemplo:
$post->comments()->save($comment);
para adicionar registro no segundo modelo ( BelongsTo ) use o associado função de
exemplo:
$user->account()->associate($account); $user->save();
em um para muitos :
Você tem que usar HasMany no primeiro modelo e BelongsTo no segundo modelo
para adicionar registro na primeira tabela ( HasMany ) use o save ou saveMany funções
exemplo:
$post->comments()->saveMany($comments);
para adicionar registro no segundo modelo ( BelongsTo ) use o associado função de
exemplo:
$user->account()->associate($account); $user->save();
de muitos para muitos :
Você deve usar BelongsToMany no primeiro modelo e BelongsToMany no segundo modelo
para adicionar registros na tabela dinâmica, use as funções de anexar ou sincronizar
ambas as funções aceitam ID único ou matriz de IDs
a diferença é o anexo verifica se o registro já existe na tabela dinâmica enquanto a sincronização não
exemplo:
$user->roles()->attach($roleId);
em polimórfico um para muitos :
Você tem que usar MorphMany no modelo principal e MorphTo em todos os modelos (*** capazes)
para adicionar registros em todos os outros modelos, use o botão salvar
exemplo:
$course->tags()->save($tag);
a tabela dinâmica deve ter as seguintes colunas:
. ID do modelo principal
. (*** capaz) ID
. (*** capaz) Tipo
em polimórfico muitos para muitos :
Você deve usar MorphByMany no modelo principal e MorphToMany em todos os modelos (*** aptos)
para adicionar registros em todos os outros modelos, use o save ou saveMany
exemplo:
$course->tags()->save($tag);
exemplo:
$course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);
a tabela dinâmica deve ter as seguintes colunas:
. ID do modelo principal
. (*** capaz) ID
. (*** capaz) Tipo
em Has Many Through (atalho):
Você tem que usar HasManyThrough na primeira tabela e ter as relações normais nas outras 2 tabelas
isso não funciona para relacionamentos ManyToMany (onde há uma tabela dinâmica)
no entanto, há uma solução fácil e agradável apenas para isso.
Aqui está um artigo que escrevi, inspirado por esta resposta. Importante verificar: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
fonte
updateMany
algo parecido? obrigadosyncWithoutDetaching([$id_one, $id_two, $id_three]);
é o que você está procurando. Na verdade, ele faz exatamente a coisa que [sync
com o segundo parâmetrofalse
] faz!fonte
A
sync
função oblitera os relacionamentos existentes e torna seu array a lista inteira de relacionamentos. Emattach
vez disso, você deseja adicionar relações sem remover outras.fonte