Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Здравствуйте!
Пытаюсь подключить TW Elements к Laravel 8. Всё делаю строго по документации. Чтобы не думалось, даже начал пустой проект.
Но в результате не подгружаются JS скрипты необходимые для работы TW Elements.
Что у меня получилось:
Файл postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Файл tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./resources/**/*.vue",
"./node_modules/tw-elements/dist/js/**/*.js"
],
theme: {
extend: {},
},
darkMode: "class",
plugins: [require("tw-elements/dist/plugin.cjs")]
}
Файл webpack.mix.js
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
//
]);
Файл resources/css/app.css
@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap");
@tailwind base;
@layer base {
html {
@apply text-[#4f4f4f];
}
html.dark {
@apply text-neutral-50;
@apply bg-neutral-800;
}
}
@tailwind components;
@tailwind utilities;
Файл resources/js/app.js
require('./bootstrap');
import 'tw-elements';
import { Tooltip, initTE } from "tw-elements";
initTE({ Tooltip });
Работа команды npm run dev проходит гладко, ошибок нет. Бандлы создаются.
Но при попытке открыть страницу в консоли JS я вижу следующие ошибки:
app.js:24157 Uncaught TypeError: Cannot read properties of null (reading 'appendChild')
at De (app.js:24157:37)
at ./node_modules/tw-elements/dist/js/tw-elements.es.min.js (app.js:24163:20)
at __webpack_require__ (app.js:35758:42)
at ./resources/js/app.js (app.js:2065:69)
at __webpack_require__ (app.js:35758:42)
at app.js:36032:64
at __webpack_require__.O (app.js:35795:23)
at app.js:36034:53
at app.js:36036:12
И вот тут у меня затык.
Буду признателен за помощь.
Спасибо, разобрался. Причина крылась в параметре retry_after конфигурации очереди (файл config/queue.php)
Этот параметр должен быть на несколько секунд больше, чем свойства задачи $timeout;
Цитата из документации:
The --timeout value should always be at least several seconds shorter than your retry_after configuration value. This will ensure that a worker processing a frozen job is always terminated before the job is retried. If your --timeout option is longer than your retry_after configuration value, your jobs may be processed twice.
Добры день! Помогите разобраться с очередями. При локальной отладке всё работает, но на рабочем сервере Job запускается два раза. Job становится в очередь по расписанию в app\Console\Kernel.php:
$schedule->job(new PrepareNoCheckMailsJob())->dailyAt('09:00');
Воркер тоже запускается там же, только каждую минуту:
$schedule->command('queue:work --stop-when-empty')->everyMinute();
Задача создаётся и попадает в таблицу jobs.
В самой задаче заданы следующие параметры:
public $tries = 3;
public $timeout = 240;
В задаче есть логирование начала и окончание её выполнения. Судя по логам, ровно через две минуты, задача запускается повторно. Исключение — если задача успевает выполнится в эти самые две минуты.
Пытался запускать воркер таким образом:
$schedule->command('queue:work --once')->everyMinute();
Всё равно ровно через две минуты задача запускается повторно.
И почему две минуты мне тоже не понятно.
Локально воспроизвести такое поведение не могу.
Посоветуйте, как обуздать воркер?
Спасибо!
Помогли решить проблему в ТГ.
Я запускал фабрику в тинкере. Следовало перезапустить сессию Тинкер.
Здравствуйте!
Есть фабрика моделей (Laravel 8):
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class UsersRelationFactory extends Factory
{
public function definition(): array
{
return [
'contragent_id' => 31,
'state' => 1,
'user_id' => function() {
return User::factory()->create()->id;
},
];
}
}
На выходе в user_id получаю неадекватные значения пользователей, которые уже есть в БД. Новая запись в таблице users не появляется
Сам по себе вызов User::factory()->create() работает. Новая запись в таблице появляется, ID верный.
Что я не так делаю? По сути мне нужно заполнить pivot таблицу, связав контрагента с id 31 с фейковыми пользователями, имеющими статус 1.
Да с сырым SQL понятно, хочется просто разобраться с этим зверем. В общем-то я задачу решил, причём двумя способами. Первый оказался клуджем. Работает, но в теории не должен Второй сделал точно по теории, но всё-таки пришлось использовать join. Я хотел попрактиковать именно отказ от джойнов, но, оказывается, не для всех задач это возможно.
Упростил реальную задачу из жизни, выкинув ненужные связи и свёл до двух таблиц.
Есть 2 таблицы: carriers и vehicles. carriers - главная, vehicles соподчинённая, соединены отношением один ко многим.
Поля в carriers: id, name, user_id (внешний ключ на третью страницу). Поля в vehicles: id, name, carrier_id
Мне нужно получить их произведение.
В SQL делаю запрос:
select
v.*, c.name as carrier_name
from
vehicles v
join
carriers c on c.id = v.carrier_id
where
c.user_id = 2
order by c.name, v.id
На выходе 9 штук.
Переписать код в Query Bilder я могу, но не вижу смысла.
Интересует, как подобные объединения получать в ORM?
Я пытался сделать вот так:
$vehicle-> Vehicle::with(['carrier'=>function(BelongsTo $query){
$query->where('user_id', '=', '1');
Ъ])
->orderBy('id')->get();
Но в результате я получаю все записи из таблицы vehicles. Как ограничить выборку только теми значениями, что мне нужны?
Спасибо!
Проблему решил. Удалять поле не надо. Надо к готовому полю применить метод $table->foreign
На выходе получим
public function up()
{
Schema::table('vehicles', function (Blueprint $table) {
$table->foreign('vehicle_type_id')->references('id')->on('vehicle_types');
});
}
public function down()
{
Schema::table('vehicles', function (Blueprint $table) {
$table->dropForeign('vehicles_vehicle_type_id_foreign');
});
}
Здравствуйте!
Есть таблица с полем 'vehicle_type_id' типа bigint. Требуется превратить его во внешний ключ и связать с другой таблицей.
Правильно ли я понимаю, что мне потребуется создать две миграции.
В первой в методе up я удаляю данное поле, а в методе down создаю.
public function up()
{
Schema::table('vehicles', function (Blueprint $table) {
$table->dropColumn('vehicle_type_id');
});
}
public function down()
{
Schema::table('vehicles', function (Blueprint $table) {
$table->bigInteger('vehicle_type_id')->change();
});
}
Во второй в методе up создаю поле и делаю из него внешний ключ, в методе down удаляю
public function up()
{
Schema::table('vehicles', function (Blueprint $table) {
$table->foreignId('vehicle_type_id')->references('id')->on('vehicle_types');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('vehicles', function (Blueprint $table) {
$table->foreignId('vehicle_type_id');
});
}
Или есть какой-либо более простой способ, аналогичный SQL
ALTER TABLE public.vehicles
ADD CONSTRAINT vehicles_fk FOREIGN KEY (vehicle_type_id)
REFERENCES public.vehicle_types(id)
Спасибо!
не буду пытаться чему-то учить.
Ну вот. А я только собрался поучиться.
Потому что так устроен стек обработки запроса.
Ага, т.е. просто потому, что фреймворк так работает.
создается экземпляр объекта этого контроллера
и при создании объекта ему ничего не передаётся? Что-то вроде new Class();
Просто в Кохане при создании класса ему передавался $request и $response, а к сессии я получал доступ через Session::instance();
Хотя, как я понимаю, мне никто не запрещает использовать $_SESSION, кроме понимания, что это будет слишком костыльно и выбиваться из концепции фреймворка.
Правильно ли я понимаю, что в случае с Laravel правильным подходом видится именно использование посредников (middleware), в котором мне будет доступна session?
И разрешите ещё глупые вопросы: в посредниках доступен фасад DB, или есть иные способы достучаться до базы данных? Само собой pg_connect никто не отменял, но это опять выглядит костыльно.
Спасибо!
почитайте раздел Аунтефикация
Мир не завязан на шаблонных моделях из коробки. БД УЖЕ существует и прекрасно работает. Никто не собирается заниматься переделками под Laravel. Требуется прикрутить веб-морду к уже рабочей базе, а не рихтовать рабочую базу под модуль Auth одного из фреймворков. Кстати, в проекте используется сырой SQL.
Конструктор контроллера выполняется ДО того как обрабатываются куки и происходит идентификация пользователя.
Как я понимаю (если не прав, поправьте), ядро фреймворка получает запрос, смотрит в конфиг роутинга и создаёт нужный класс. При создании класса вызывается конструктор, если он есть в наличии. Мне не совсем понятно, почему я могу получить доступ к сессии из любого метода класса, а из конструктора не могу.
Кстати, я действительно воспользовался middleware.
Здравствуйте!
Существует БД на PostgreSQL, со своей собственной системой хранения пользователей и их ролей. Требуется сделать веб-приложение, для работы с этой БД.
Ранее у меня был опыт работы во фреймворке Kohana, но он сдох, поэтому я выбрал Laravel.
Этот опыт со мною играет злую шутку. Начал делать так, как дела всегда. Создаю контроллер-предка, в котором выполняю все однотипные действия, присущие унаследованным контроллерам.
Обычно я в этом предке проверял, аутентифицирован ли пользователь, и если нет, редиректил его на страницу логина. Таким образом все остальные страницы оказывались недоступны неаутентифицированному пользователю.
Здесь я пошёл этим же путём. Добавил в уже существующий контроллер Controller.php нужный функционал и в теле конструктора делают редирект к нужному мне адресу:
public function __construct()
{
// тут какой-то код
if (!$this->IsAuth()) return redirect('/user');
}
Но эта директива ни к чему не приводит. Просто не работает.
Вчитался в маны. Вычитал, что я могу передать управление в посредник. Сделал свой посредник, написал тестовую функцию, зарегистрировал его в Kernel.php
public function handle(Request $request, Closure $next)
{
if (true) return redirect('/user');
return $next($request);
}
Прописал роутинг
Route::get('test', [MainController::class, 'test'])->middleware('CheckAuth');
На выходе браузер ругается: ERR_TOO_MANY_REDIRECTS
Подскажите, что я делаю не так и как можно реализовать редирект?
Спасибо!
Страницы 1