Skip to main content

UpdateLanguageRequest

The UpdateLanguageRequest is a FormRequest class that validates and normalizes data when updating existing language records. It provides flexible validation that handles partial updates and ensures data integrity.

Namespace​

JobMetric\Language\Http\Requests\UpdateLanguageRequest

Overview​

UpdateLanguageRequest provides:

  • Flexible Validation: All fields are optional (partial updates supported)
  • Context-Aware Rules: Automatically extracts language ID from route for uniqueness validation
  • Data Normalization: Automatically normalizes input data
  • Static Methods: Can be used outside Laravel's request pipeline with explicit context
  • Custom Attributes: Provides translated field names for error messages

Key Differences from StoreLanguageRequest​

FeatureStoreLanguageRequestUpdateLanguageRequest
FieldsAll requiredAll optional (partial updates)
Locale UniquenessChecks against all languagesExcludes current language from check
Language IDNot neededExtracted from route parameter
Static Methodsnormalize($data)normalize($data, $ctx) and rulesFor($data, $ctx)

Available Methods​

Rules​

Get validation rules for language update:

public function rules(): array

Returns: array - Validation rules array

Behavior:

  • Automatically extracts language ID from route parameter language
  • Passes language ID to CheckLocaleRule to exclude current record from uniqueness check

Example:

// Route: PUT /languages/{language}
// $language is the route parameter
$request = new UpdateLanguageRequest();
$rules = $request->rules(); // Automatically uses language ID from route

Rules For (Static)​

Build rules with explicit context (used outside Laravel pipeline):

public static function rulesFor(array $data, array $ctx = []): array

Parameters:

  • $data (array): Input data
  • $ctx (array): Context array containing language_id

Returns: array - Validation rules array

Example:

$data = ['name' => 'Updated Name', 'locale' => 'fa'];
$context = ['language_id' => 5];

$rules = UpdateLanguageRequest::rulesFor($data, $context);
// Rules include CheckLocaleRule(5) to exclude language ID 5 from uniqueness check

Normalize (Static)​

Normalize raw input data outside Laravel's FormRequest pipeline:

public static function normalize(array $data, array $ctx = []): array

Parameters:

  • $data (array): Raw input data
  • $ctx (array): Context array (optional, not used in normalization)

Returns: array - Normalized data

What it does:

  • Converts empty flag string to null

Example:

$rawData = [
'name' => 'Updated Persian',
'flag' => '', // Empty string
];

$normalized = UpdateLanguageRequest::normalize($rawData);
// Result: ['name' => 'Updated Persian', 'flag' => null]

Attributes​

Get custom attribute names for validation error messages:

public function attributes(): array

Returns: array - Attribute names mapped to translated labels

Validation Rules​

Complete Rules Array​

[
'name' => 'string',
'flag' => 'string|nullable',
'locale' => ['string', new CheckLocaleRule($languageId)],
'direction' => 'string|in:ltr,rtl',
'calendar' => 'string|in:gregorian,jalali,hijri,hebrew,buddhist,coptic,ethiopian,chinese',
'status' => 'boolean',
]

Note: All fields are optional, allowing partial updates.

Field Details​

FieldTypeRulesDescription
namestring|nullstringLanguage display name (optional)
flagstring|nullstring|nullableCountry flag code (optional)
localestring|nullstring, CheckLocaleRule($id)Two-letter locale code (optional, excludes current language)
directionstring|nullstring, in:ltr,rtlText direction (optional)
calendarstring|nullstring, in:...Calendar system type (optional)
statusbool|nullbooleanActive/inactive status (optional)

Locale Uniqueness Handling​

The locale field uses CheckLocaleRule with the current language ID:

// When updating language ID 5
'locale' => ['string', new CheckLocaleRule(5)]

// This ensures:
// - Locale format is valid
// - Locale is unique (excluding language ID 5)
// - Can update other fields without changing locale

Usage Examples​

Example 1: Basic Controller Usage​

// app/Http/Controllers/LanguageController.php
use JobMetric\Language\Http\Requests\UpdateLanguageRequest;
use JobMetric\Language\Facades\Language;

public function update(UpdateLanguageRequest $request, Language $language)
{
$data = $request->validated();

$updated = Language::update($language->id, $data);

return response()->json([
'message' => 'Language updated successfully',
'language' => $updated,
]);
}

Example 2: Partial Update​

// Only update name
$request->validate([
'name' => 'required|string',
]);

// Only update status
$request->validate([
'status' => 'required|boolean',
]);

// Update multiple fields
$request->validate([
'name' => 'required|string',
'status' => 'required|boolean',
'direction' => 'required|string|in:ltr,rtl',
]);

Example 3: Using Static Methods Outside Pipeline​

// app/Services/LanguageSyncService.php
use JobMetric\Language\Http\Requests\UpdateLanguageRequest;
use JobMetric\Language\Facades\Language;

class LanguageSyncService
{
public function syncLanguage(int $languageId, array $externalData): Language
{
// Normalize data
$normalized = UpdateLanguageRequest::normalize($externalData);

// Build rules with context
$rules = UpdateLanguageRequest::rulesFor($normalized, [
'language_id' => $languageId
]);

// Validate manually
$validator = Validator::make($normalized, $rules);

if ($validator->fails()) {
throw new ValidationException($validator);
}

// Update language
return Language::update($languageId, $normalized);
}
}

Example 4: API Endpoint​

// routes/api.php
Route::put('/languages/{language}', function (UpdateLanguageRequest $request, Language $language) {
$updated = Language::update($language->id, $request->validated());

return new LanguageResource($updated);
});

Example 5: Form Submission​

// app/Http/Controllers/Admin/LanguageController.php
public function update(UpdateLanguageRequest $request, Language $language)
{
$updated = Language::update($language->id, $request->validated());

return redirect()
->route('admin.languages.index')
->with('success', 'Language updated successfully');
}

Example 6: Bulk Language Update​

// app/Http/Controllers/Admin/LanguageController.php
public function bulkUpdate(Request $request)
{
$request->validate([
'languages' => 'required|array',
'languages.*.id' => 'required|exists:languages,id',
'languages.*.data' => 'required|array',
]);

$updated = [];

foreach ($request->input('languages') as $item) {
$languageId = $item['id'];
$languageData = $item['data'];

// Normalize data
$normalized = UpdateLanguageRequest::normalize($languageData);

// Build rules with context
$rules = UpdateLanguageRequest::rulesFor($normalized, [
'language_id' => $languageId
]);

// Validate
$validator = Validator::make($normalized, $rules);

if ($validator->fails()) {
continue; // Skip invalid entries
}

$updated[] = Language::update($languageId, $normalized);
}

return response()->json([
'message' => count($updated) . ' languages updated',
'languages' => $updated,
]);
}

Example 7: Changing Locale​

// Update language locale from 'fa-IR' to 'fa'
public function update(UpdateLanguageRequest $request, Language $language)
{
// Request includes: ['locale' => 'fa']
// CheckLocaleRule(5) ensures 'fa' doesn't exist (excluding language ID 5)

$updated = Language::update($language->id, $request->validated());

return response()->json($updated);
}

Example 8: With Authorization​

// app/Http/Requests/UpdateLanguageRequest.php
use Illuminate\Foundation\Http\FormRequest;

class UpdateLanguageRequest extends FormRequest
{
public function authorize(): bool
{
$language = $this->route('language');

// Only allow updating if user owns the language or is admin
return auth()->id() === $language->created_by
|| auth()->user()->isAdmin();
}

// ... rest of the class
}

Route Parameter Extraction​

The request automatically extracts the language ID from the route:

// Route definition
Route::put('/languages/{language}', [LanguageController::class, 'update']);

// In UpdateLanguageRequest
$language_id = $this->route()?->parameter('language')?->id;
// or
$language_id = $this->route('language')->id;

Note: The route parameter name must be language for automatic extraction.

Data Normalization​

The normalize() method automatically handles:

Empty Flag String​

// Input
['flag' => '']

// Output
['flag' => null]

Partial Updates​

// Input - only updating name
['name' => 'Updated Name']

// Output - same, no other fields affected
['name' => 'Updated Name']

When to Use UpdateLanguageRequest​

Primary Use Cases​

1. Language Update Forms​

When: Creating admin forms for editing existing languages.

Why: Provides flexible validation for partial updates.

Example:

public function update(UpdateLanguageRequest $request, Language $language)
{
$updated = Language::update($language->id, $request->validated());
return redirect()->back()->with('success', 'Language updated');
}

2. API Endpoints​

When: Building REST APIs for language management.

Why: Ensures data integrity while allowing partial updates.

Example:

Route::put('/api/languages/{language}', function (UpdateLanguageRequest $request, Language $language) {
return new LanguageResource(Language::update($language->id, $request->validated()));
});

3. Language Sync​

When: Syncing languages from external sources.

Why: Normalizes and validates data with proper context.

Example:

$normalized = UpdateLanguageRequest::normalize($externalData);
$rules = UpdateLanguageRequest::rulesFor($normalized, ['language_id' => $id]);

4. Bulk Updates​

When: Updating multiple languages at once.

Why: Consistent validation with proper context for each language.

Example:

foreach ($languages as $id => $data) {
$rules = UpdateLanguageRequest::rulesFor($data, ['language_id' => $id]);
// Validate and update
}

When NOT to Use​

  • Creating Languages: Use StoreLanguageRequest instead
  • Reading Languages: Don't use for reading/displaying language data
  • Deleting Languages: Use appropriate delete request
  • Internal Logic: Don't use for internal language operations

Best Practices​

1. Always Use in Controllers​

// ✅ Good
public function update(UpdateLanguageRequest $request, Language $language)
{
$updated = Language::update($language->id, $request->validated());
}

// ❌ Bad
public function update(Request $request, Language $language)
{
$request->validate([...]); // Duplicate validation
$updated = Language::update($language->id, $request->all());
}

2. Use Validated Data​

// ✅ Good - Only validated data
$updated = Language::update($language->id, $request->validated());

// ❌ Bad - All input data
$updated = Language::update($language->id, $request->all());

3. Use Static Methods with Context​

// ✅ Good - Explicit context
$rules = UpdateLanguageRequest::rulesFor($data, ['language_id' => $id]);

// ❌ Bad - Missing context
$rules = (new UpdateLanguageRequest())->rules(); // May not work outside pipeline

4. Handle Partial Updates​

// ✅ Good - Only update provided fields
$data = $request->validated(); // Only contains provided fields
$updated = Language::update($language->id, $data);

// ❌ Bad - Merge with existing data unnecessarily
$data = array_merge($language->toArray(), $request->validated());

Common Mistakes to Avoid​

  1. Not using validated data:

    // ❌ Wrong
    $updated = Language::update($language->id, $request->all());

    // ✅ Correct
    $updated = Language::update($language->id, $request->validated());
  2. Wrong route parameter name:

    // ❌ Wrong - route parameter must be 'language'
    Route::put('/languages/{lang}', ...);

    // ✅ Correct
    Route::put('/languages/{language}', ...);
  3. Not providing context in static methods:

    // ❌ Wrong - missing language_id context
    $rules = UpdateLanguageRequest::rulesFor($data);

    // ✅ Correct
    $rules = UpdateLanguageRequest::rulesFor($data, ['language_id' => $id]);
  4. Duplicating validation rules:

    // ❌ Wrong
    $request->validate(['locale' => 'required|string|unique:languages,locale,' . $id]);

    // ✅ Correct - Use the request class
    // Validation is already in UpdateLanguageRequest

Comparison with StoreLanguageRequest​

FeatureStoreLanguageRequestUpdateLanguageRequest
PurposeCreate new languagesUpdate existing languages
FieldsAll requiredAll optional
Locale CheckChecks all languagesExcludes current language
Language IDNot neededExtracted from route
Static Methodsnormalize($data)normalize($data, $ctx), rulesFor($data, $ctx)
Use CaseNew language creationLanguage updates