У меня есть модель пользователя Eloquent, которая принимает экземпляр класса UserMailer в его конструкторе, но я получаю эту ошибку
Argument 1 passed to User::__construct() must be an instance of TrainerCompare\Mailers\UserMailer, none given, called in /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 631 and defined
Я понимаю ошибку, но не могу понять, что я сделал неправильно, но я не очень хорошо разбираюсь в пространстве имен и композиции класса классов vs psr0. Я помню, как использовать компоновщик dump-autoload, так что это не так
соответствующая структура папок
composer.json app/ models/ User.php TrainerCompare/ Mailers/ Mailer.php UserMailer.php Services/ Validation/
раздел автозагрузки composer.json. Раздел psr-0 есть, когда я добавил службу проверки, которую вы можете увидеть в TrainerCompare /, и эти классы отлично работают. Я добавил приложение / TrainerCompare / Mailers к classmap за учебник, за которым я следую, чтобы загрузить классы почтовых программ
"autoload": { "classmap": [ "app/commands", "app/controllers", "app/models", "app/database/migrations", "app/database/seeds", "app/tests/TestCase.php", "app/tests/helpers", "app/TrainerCompare/Mailers" ], "psr-0":{ "TrainerCompare": "app/" } }
User.php
<?php use Illuminate\Auth\UserInterface; use Illuminate\Auth\Reminders\RemindableInterface; use TrainerCompare\Mailers\UserMailer as Mailer; class User extends BaseModel implements UserInterface, RemindableInterface { protected $mailer; public function __construct(Mailer $mailer) { $this->mailer = $mailer; } }
Mailer.php
<?php namespace TrainerCompare\Mailers; use Mail; /** * Email mailing class */ abstract class Mailer { public function __construct() { # code... } public function sendTo($user, $subject, $view, $data = []) { Maill::send($view, $data, function ($message) use ($user, $subject) { $message->to($user->email) ->subject($subject); }); } }
UserMailer.php
<?php namespace TrainerCompare\Mailers; use User; /** * User Mailer Class */ class UserMailer extends Mailer { public function __construct() { # code... } public function welcome($user) { $view = 'emails.users.welcome'; $data = []; $subject = 'Welcome to Laracsts'; return $this->sendTo($user, $subject, $view, $data); } }
Красноречивый (ре) создает себя внутренне, вызывая:
new static
Примером является создание нового запроса:
return with(new static)->newQuery();
Я не уверен, что автоматическое разрешение зависимостей будет работать в этом случае, оно всегда должно работать внутри laravel, но поскольку у него также есть собственный метод конструктора, вы должны хотя бы перенаправить вызов и поддерживать параметр $attribute
:
public function __construct(array $attributes = array(), Mailer $mailer) { $this->mailer = $mailer; parent::__construct($attributes); }
РЕДАКТИРОВАТЬ
Открыл вопрос, чтобы понять это: https://github.com/laravel/framework/issues/3862
EDIT 2
Как я уже сказал в комментарии, лучше создать сервис, как указано самим, является лучшим дизайном приложения. Вы не должны использовать свою модель для отправки электронной почты. Служба, которая получает пользовательскую модель (или просто имя и адрес электронной почты) и отправляет сообщение этому пользователю, будет лучшим способом.
Ответ, данный Тейлором Отуэлл об этом в выпуске:
Модели на самом деле не предназначены для того, чтобы в них были введены зависимости. Я думаю, что это просто стиль ORM ActiveRecord. Я бы предложил передать пользователь в класс Mailer или что-то подобное. Или, если вам это нравится, вы можете использовать App :: make, чтобы захватить экземпляр Mail из экземпляра модели, особенно если вам нужна только эта зависимость от одного метода.