Правило Rule::contains() для валідації масивів у Laravel

Перекладено ШІ
Оригінал: Laravel News
Оновлено: 12 липня, 2025
Ви вже чули про новий метод `Rule::contains()` у Laravel? Ця функція спрощує валідацію масивів, пропонуючи зрозумілу та елегантну альтернативу старим способам, що значно покращує читабельність коду. Читайте далі, щоб дізнатися, як цей метод може допомогти вам у вашій розробці

Метод Rule::contains() в Laravel інтегрує валідацію масивів у флюїдний інтерфейс, пропонуючи єдиний синтаксис, який узгоджується з іншими правилами валідації та підвищує читабельність коду.

Раніше для перевірки вмісту масивів потрібно було використовувати конкатенацію рядків та ручне оброблення значень:

'tags' => 'contains:' . implode(',', $allowedTags)

Новий флюїдний підхід усуває необхідність у зборі рядків і гармонійно вписується у валідаційні шаблони Laravel.

use Illuminate\Validation\Rule;

'tags' => Rule::contains(['technology', 'programming', 'laravel'])

Ось приклад комплексної системи управління контентом, що демонструє різні застосування Rule::contains():

class ContentController extends Controller
{
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'content_type' => [
                'required',
                'string',
                Rule::in(['article', 'tutorial', 'news', 'review'])
            ],
            'categories' => [
                'required',
                'array',
                'min:1',
                Rule::contains(['technology', 'business', 'lifestyle'])
            ],
            'permissions' => [
                'required',
                'array',
                Rule::contains([
                    Permission::READ->value,
                    Permission::WRITE->value
                ])
            ],
            'target_platforms' => [
                'sometimes',
                'array',
                Rule::contains(['web', 'mobile', 'api'])
            ],
            'notification_channels' => [
                'nullable',
                'array',
                Rule::contains(['email', 'sms', 'push', 'slack'])
            ]
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $content = Content::create([
            'title' => $request->input('title'),
            'body' => $request->input('body'),
            'content_type' => $request->input('content_type'),
            'categories' => $request->input('categories'),
            'permissions' => $request->input('permissions'),
            'author_id' => auth()->id()
        ]);

        if ($request->has('target_platforms')) {
            $this->scheduleContentDistribution($content, $request->input('target_platforms'));
        }

        if ($request->has('notification_channels')) {
            $this->sendCreationNotifications($content, $request->input('notification_channels'));
        }

        return response()->json([
            'message' => 'Контент успішно створено',
            'content' => $content->load('author')
        ]);
    }

    public function updateSettings(Request $request)
    {
        $allowedThemes = ['light', 'dark', 'auto'];
        $allowedLanguages = ['en', 'es', 'fr', 'de', 'it'];
        $allowedNotifications = ['immediate', 'daily', 'weekly', 'monthly'];

        $validator = Validator::make($request->all(), [
            'user_preferences' => 'required|array',
            'user_preferences.themes' => [
                'required',
                'array',
                Rule::contains($allowedThemes)
            ],
            'user_preferences.languages' => [
                'required',
                'array',
                Rule::contains($allowedLanguages)
            ],
            'user_preferences.notification_frequency' => [
                'required',
                'array',
                Rule::contains($allowedNotifications)
            ],
            'admin_features' => [
                'sometimes',
                'array',
                Rule::contains([
                    AdminFeature::USER_MANAGEMENT->value,
                    AdminFeature::CONTENT_MODERATION->value,
                    AdminFeature::ANALYTICS_ACCESS->value
                ])
            ]
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $user = auth()->user();
        $preferences = $request->input('user_preferences');

        $user->update([
            'preferences' => $preferences,
            'updated_at' => now()
        ]);

        if ($request->has('admin_features') && $user->isAdmin()) {
            $this->updateAdminPermissions($user, $request->input('admin_features'));
        }

        return response()->json([
            'message' => 'Налаштування успішно оновлені',
            'preferences' => $user->fresh()->preferences
        ]);
    }

    private function scheduleContentDistribution(Content $content, array $platforms)
    {
        foreach ($platforms as $platform) {
            ContentDistributionJob::dispatch($content, $platform)
                ->delay(now()->addMinutes(5));
        }
    }

    private function sendCreationNotifications(Content $content, array $channels)
    {
        foreach ($channels as $channel) {
            NotificationService::send($channel, new ContentCreatedNotification($content));
        }
    }

    private function updateAdminPermissions($user, array $features)
    {
        $user->adminPermissions()->sync($features);
    }
}

enum Permission: string
{
    case READ = 'read';
    case WRITE = 'write';
    case DELETE = 'delete';
    case PUBLISH = 'publish';
}

enum AdminFeature: string
{
    case USER_MANAGEMENT = 'user_management';
    case CONTENT_MODERATION = 'content_moderation';
    case ANALYTICS_ACCESS = 'analytics_access';
    case SYSTEM_SETTINGS = 'system_settings';
}

Метод Rule::contains() забезпечує узгодженість з екосистемою валідації Laravel та пропонує чистішу й легшу для підтримки логіку валідації масивів