Laravel de tabela dinâmica a criar a associação de uma vez e, em seguida, actualizar

StackOverflow https://stackoverflow.com//questions/23019239

  •  21-12-2019
  •  | 
  •  

Pergunta

Eu tenho as seguintes tabelas:

Usuário:

userID
...

Lição:

lessonID
...

Users_Lessons_Status (que atua como uma tabela dinâmica e possui outras informações):

userID references User.userID
lessonID references Lessons.lessonID
latestSectionID
percentComplete

O que eu quero fazer é, para cada usuário, para cada lição, deve haver uma linha em uma tabela dinâmica que informa quanto o usuário tiver concluído na aula e que suas últimas seção de IDENTIFICAÇÃO foi.Isto é, deve haver um único par com userID e lessonID (chaves primárias?).

Levantei meus modelos, como por exemplo:

<?php

class User extends Eloquent implements UserInterface, RemindableInterface {

...


    public function lessonStatuses() 
    {
        return $this->belongsToMany('Lesson', 'users_lessons_status', 'lessonID', 'userID')->withPivot('latestSectionID', 'percentComplete');
    }

}

<?

class Lesson extends Eloquent {

protected $table = 'lessons';
protected $primaryKey = 'lessonID';

public function userStatuses()
{
    return $this->belongsToMany('User', 'users_lessons_status', 'userID', 'lessonID');
}


}

?>

Minha rota actual parecido com este:

Route::post('dbm/users/setLatestSectionID', function() {
    if(Auth::check()) {
        $user = User::find(Input::get('userID'));
        $lesson = Lesson::find(Input::get('lessonID'));
        $us = $user->lessonStatuses(); 
        $us->attach($lesson->lessonID, 
            ["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
    }
});

Isso funciona, no entanto, cria uma nova linha de cada vez que eu atualizar para o mesmo userID e lessonID, de modo que o par não é mais exclusivo.Quais os métodos que devo usar para este propósito?Eu tentei tanto save(), attach() e push() na documentação, mas não tenho certeza de qual usar aqui.

Editar:para esclarecer, a tabela resultante deve ser algo como isto:

id|userID|lessonID|latestSectionID|percentComplete
1    1      1             X             Y
2    1      2        
3    1      3         
4    2      1          
5    3      1
6    3      2
....

Edit 2:Fixo o User->belongsToMany() método e adicionado a withPivot chamada.

Foi útil?

Solução

Ele parece um erro, no entanto, você pode fazer isso:

...->sync([$id], false); // detaching set to false, so it will only insert new rows, skip existing and won't detach anything

editar:Como disse em comentário - não vai funcionar para você, como você deseja conjunto de dados da tabela dinâmica.Então, basicamente, não existe nenhum método para fazer isso no momento, mas algo como isso deve fazer:

// belongsToMany.php
public function attachOrUpdate($id, array $attributes = array(), $touch = true)
{
    if ($id instanceof Model) $id = $id->getKey();

    if ( ! $this->allRelatedIds()->contains($id)) // getRelatedIds() in prior to v5.4
    {
        return $this->attach($id, $attributes, $touch); 
    }
    else if ( ! empty($attributes))
    {
        return $this->updateExistingPivot($id, $attributes, $touch);
    }
}

Eu vou testá-lo e se ele passa, envie uma solicitação para 4.1

Outras dicas

Eu enfrentei isso recentemente e fixa-lo desta forma:

Utilização updateExistingPivot primeiro e verifique o resultado , se o resultado for 1 isso significa que havia linha com o mesmo userID e lessonID e tem sido atualizado com êxito, caso contrário, se o resultado for 0 isso significa que não havia linhas com esse userID e lessonID, assim você pode anexá-lo a fim de criar nova linha

    $update_result = $us->updateExistingPivot($lesson->lessonID, 
            ["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
    if($update_result == 0) {
        $us->attach($lesson->lessonID, 
            ["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
    }

Você deve estar usando updateExistingPivot().

Atualizar seu código para usar

    $us->updateExistingPivot($lesson->lessonID, 
        ["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')], true );

O último parâmetro irá atualizar os carimbos de data / hora para todos os modelos relacionados.Se não, você pode remover ou definido para false.

Se você deseja anexar apenas quando um registro não existir, você poderia fazer algo parecido com isso...

Route::post('dbm/users/setLatestSectionID', function() {
    if(Auth::check()) {
        $user = User::find(Input::get('userID'));

        $lesson = [
            "latestSectionID" => Input::get('latestSectionID'), 
            "percentComplete" => Input::get('percentComplete')
        ];

        $num_lessons = $user->lessonStatuses()->where('id', Input::get('lessonID'))->count();

        if($num_lessons == 0) {
            $user->attach($lesson->lessonID, $lesson);
        } else {
            $user->updateExistingPivot($lesson->lessonID, $lesson);

        }
    }
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top