2016-04-09 3 views
0

У меня возникла странная проблема с красноречивым.Laravel eloquent unguarded во время посева

У меня есть две красноречивые модели, модель пользователя и модель профиля, которые имеют отдельные таблицы и имеют отношение один к одному.

У меня есть единая форма, в которой передаются данные для обеих этих моделей. Поэтому данные, принадлежащие пользователю и профилю, присутствуют в форме.

Я попытался выполнить вставки в чисто как можно дальше от регулятора:

$user = $this->users->createUser($request->all()); 

функция createUser определяется как этот

public function createUser(array $data) 
{ 
    $user = new User($data); 
    // set some non relevant user options here... 
    $user->save(); 

    $profile = new Profile($data); 
    $user->profile()->save($profile); 

    return $user; 
} 

Но это производит ошибку SQL, так красноречивы присваивает все значения из формы для обеих моделей, поэтому пользователь и профиль получают одинаковые свойства, поэтому красноречивый пытается вставить в столбцы, которые не существуют для данной модели.

Я думал, что $fillable поле используется для предотвращения такого рода вещи не случилось, но у меня есть $fillable поля, определенные в обеих моделях:

// User 
protected $fillable = ['email', 'password', ...]; 

// Profile 
protected $fillable = ['first_name', 'last_name', ...]; 

Я также попытался это: (new User)->fill($data) но не работает, и не следует, так как метод fill также вызывается из конструктора Model.

На мой взгляд, это не ожидаемое поведение, но опять же, возможно, я неправильно понял понятие заполнения. Любое понимание было бы оценено. Я знаю, что это можно решить, объявив каждый ключ, который я хочу отправить конструктору, но это кажется мне очень грязным. Кроме того, я использую Laravel v5.2.29

EDIT

После дальнейшего тестирования я пришел к выводу, что это происходит только внутри, когда я бегу сеялок базы данных, где я использую эти функции. Копая глубже, я вижу, что это имеет прекрасный смысл, так как запуск команды «unguards» начального базового класса модели. Так что это ожидаемое поведение.

Мой вопрос в том, есть ли способ переопределить это значение по умолчанию, чтобы модели не получали «неохраняемый» при запуске команды seed, чтобы я мог использовать мои вспомогательные функции для заполнения моей тестовой базы данных или делать Я должен правильно определить каждую запись данных вручную внутри классов сеялки?

+0

У вас есть конструктор в вашей модели? Вы передаете «Пользователь» и «Профиль», чтобы убедиться, что для его работы существует конструктор. –

+0

И пользователь и профиль наследуют базовый класс Model, и я не переопределяю конструктор. Я сузил проблему (см. Мое редактирование), но я не уверен, как обойти это чистым способом. – Pavlin

+0

Почему бы не пойти на phpmyadmin или что-то еще и вставить там данные? –

ответ

2

Да, из некоторой версии Laravel 5.2 при использовании посевных моделей не охраняются, как вы заметили. На самом деле вполне разумно, что это неохраняемо, но если вы хотите его изменить, это возможно, но не так просто.

Вот шаги, которые необходимо сделать, чтобы добиться того, что:

  1. Комментарий в config/app.php линии Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, добавить добавить строку с пользовательским классом ConsoleSupportServiceProvider.

  2. Создать этот класс так же, как оригинал ConsoleSupportServiceProvider (на самом деле вы можете продлить его), но в $providers собственности изменения Illuminate\Database\SeedServiceProvider в обычае один

  3. снова создавать пользовательские SeedServiceProvider, расширяющий оригинальный SeedServiceProvider и теперь переопределить registerSeedCommand создать снова пользовательские SeedCommand класс

  4. Создание пользовательского SeedCommand класса, который расширяет оригинальный SeedCommand и в настоящее время все, что вам нужно, это изменение:

    public function fire() 
    { 
        if (! $this->confirmToProceed()) { 
         return; 
        } 
    
        $this->resolver->setDefaultConnection($this->getDatabase()); 
    
        Model::unguarded(function() { 
         $this->getSeeder()->run(); 
        }); 
    } 
    

    в

    public function fire() 
    { 
        if (! $this->confirmToProceed()) { 
         return; 
        } 
    
        $this->resolver->setDefaultConnection($this->getDatabase()); 
    
        $this->getSeeder()->run(); 
    
    } 
    
+1

Спасибо за разъяснение. Имеет смысл, что база данных должна быть неохраняемой во время процесса посева, поэтому в конце я изменил свои семена. Я попытался реализовать свою собственную команду Seed, но это не сработало, и теперь я понимаю, почему - я не менял ни одного поставщика услуг. Спасибо за отличный ответ! – Pavlin