16

In my Laravel app, I have A model that defines a relationship like:

public function vitalCategories()
{
    return $this->belongsToMany(
        'App\Models\Diagonals\VitalLabelCategory',
        'vitalLabelCategoryMap',
        'vitalLabelId',
        'vitalLabelCategoryId');
}

When I query a record like below, I expect the relation to be available with the variable name vitalCategories

$vitalLabel = VitalLabel::where('label', 'confirmation')->with(['subscribers','vitalCategories','vitals'])->first();
return json_encode($vitalLabel);

However, the above query produces the relation with the variable name 'vital_categories' like this:

enter image description here

How can I make laravel stop changing the case of my variable for the relation to snake case?

Just for grins, I also tried:

$vitalLabel = VitalLabel::where('label', 'confirmation')->with(['subscribers','vitalCategories','vitals'])->first();
$vitalLabel->load('vitalCategories');
$vitalLabel->vitalCategories = $vitalLabel->vitalCategories() ;
return json_encode($vitalLabel);

which failed to see the related models:

enter image description here

so then I tried:

$vitalLabel = VitalLabel::where('label', 'confirmation')->with(['subscribers','vitalCategories','vitals'])->first();
$vitalLabel->load('vitalCategories');
$vitalLabel->vitalCategories = $vitalLabel->vital_categories;
return json_encode($vitalLabel);

which also failed to see the related models:

enter image description here

Wesley Smith
  • 19,401
  • 22
  • 85
  • 133

1 Answers1

28

Laravel automatically converts the names of relationships from camelCase to snake_case when the model is converted to an array (toArray()) or json (toJson()).

So, the attribute on the model is actually vitalCategories, but when you dump it out as json, it will print as vital_categories.

If you would like to turn this off, you can set the $snakeAttributes property on your model to false.

public static $snakeAttributes = false;
patricus
  • 59,488
  • 15
  • 143
  • 145
  • 1
    It seems it's actually `static $snakeAttributes = false;` (static vs protected) but you nailed it, thank you! – Wesley Smith Jun 28 '17 at 05:15
  • 1
    @DelightedD0D Yeah, and it's `public`, too. Sorry, I was going more from memory than looking at the actual code. Silly me. I've updated the answer. Thanks! – patricus Jun 28 '17 at 05:17
  • Flawless answer – Gjaa Feb 25 '20 at 23:18
  • Also, since the property is public, you can set it right before you get the array, or anywhere for that matter. The key is that it's very easy to forget you don't need this during the `load()` method, rather during the `toArray()` method. – toraman Jan 05 '21 at 12:57
  • 1
    This is exactly the sort of goofy behavior that will make me leave a framework like laravel. Come on Laravel, you can do better. – WebDev-SysAdmin Mar 12 '22 at 16:56