You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I am using Spatie's translation package, and I noticed an issue when overriding toArray() in a model with translatable attributes.
My goal is to return only the translated value for the current locale when calling toArray(), instead of an array with all translations. However, overriding toArray() this way causes unintended side effects, such as breaking Laravel's replicate() method and potentially other features that rely on toArray().
Expected Behavior:
toArray() should return only the translated value for the current locale.
replicate() and other core Laravel methods should continue working as expected.
If I override toArray() in a translatable model like the documentation. Then calling replicate() on this model no longer works correctly.
Even if I pass a variable to toArray() to conditionally return translated data while maintaining its default behavior, I still encounter an issue when calling a model with relationships to translatable tables. The variable I pass is not accessible within the toArray() methods of related models.
For now, I have found a workaround: I created a trait that I include in both regular models and translatable ones:
trait ToTranslatableArray
{
/**
* Converte l'oggetto in un array.
*
* Questa funzione restituisce un array che rappresenta l'oggetto corrente.
* Se il parametro $translate è impostato su true, verrà eseguita la traduzione
* degli attributi dell'oggetto, se supportata.
*
* @param bool $translate Indica se attivare la traduzione degli attributi. Default è false.
*
* @return array Ritorna un array contenente i dati dell'oggetto, tradotti se richiesto.
*/
public function toArray(bool $translate = false): array
{
if ($translate) {
instance('translateToArray', true);
}
if (
instance('translateToArray') &&
method_exists($this, 'getTranslatableAttributes')
) {
$array = $this->toTranslatedArray();
} else {
$array = parent::toArray();
}
if ($translate) {
instance('translateToArray', false);
}
return $array;
}
/**
* Converte gli attributi dell'oggetto in un array tradotto.
*
* Questa funzione recupera gli attributi selezionati dalla query e filtra quelli
* che possono essere tradotti. Per ciascun attributo traducibile, viene ottenuta
* la traduzione corrispondente nella lingua corrente. Infine, unisce gli attributi
* tradotti con le relazioni dell'oggetto in un'unica array.
*
* @return array L'array contenente gli attributi tradotti e le relazioni.
* @link https://spatie.be/docs/laravel-translatable/v6/advanced-usage/customize-the-toarray-method
*/
protected function toTranslatedArray(): array
{
$attributes = $this->attributesToArray(); // attributes selected by the query
// remove attributes if they are not selected
$translatable = array_filter($this->getTranslatableAttributes(), function ($key) use ($attributes) {
return array_key_exists($key, $attributes);
});
foreach ($translatable as $field) {
$attributes[$field] = $this->getTranslation($field, get_lang());
}
return array_merge($attributes, $this->relationsToArray());
}
This discussion was converted from issue #490 on March 04, 2025 09:08.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi, I am using Spatie's translation package, and I noticed an issue when overriding toArray() in a model with translatable attributes.
My goal is to return only the translated value for the current locale when calling toArray(), instead of an array with all translations. However, overriding toArray() this way causes unintended side effects, such as breaking Laravel's replicate() method and potentially other features that rely on toArray().
Expected Behavior:
If I override toArray() in a translatable model like the documentation. Then calling replicate() on this model no longer works correctly.
Even if I pass a variable to toArray() to conditionally return translated data while maintaining its default behavior, I still encounter an issue when calling a model with relationships to translatable tables. The variable I pass is not accessible within the toArray() methods of related models.
For now, I have found a workaround: I created a trait that I include in both regular models and translatable ones:
trait ToTranslatableArray
{
/**
* Converte l'oggetto in un array.
*
* Questa funzione restituisce un array che rappresenta l'oggetto corrente.
* Se il parametro $translate è impostato su true, verrà eseguita la traduzione
* degli attributi dell'oggetto, se supportata.
*
* @param bool $translate Indica se attivare la traduzione degli attributi. Default è false.
*
* @return array Ritorna un array contenente i dati dell'oggetto, tradotti se richiesto.
*/
public function toArray(bool $translate = false): array
{
if ($translate) {
instance('translateToArray', true);
}
}
Beta Was this translation helpful? Give feedback.
All reactions