Skip to content
This repository was archived by the owner on Jun 18, 2019. It is now read-only.

Commit 36c729f

Browse files
authored
Merge pull request #533 from derekmd/fix-untranslated-save-n-plus-1-queries
Fix N+1 queries when updating non-translated model attributes
2 parents cf6c8dc + c1096c5 commit 36c729f

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

src/Translatable/Translatable.php

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -252,31 +252,23 @@ public function setAttribute($key, $value)
252252
*/
253253
public function save(array $options = [])
254254
{
255-
if ($this->exists) {
256-
if ($this->isDirty()) {
257-
// If $this->exists and dirty, parent::save() has to return true. If not,
258-
// an error has occurred. Therefore we shouldn't save the translations.
259-
if (parent::save($options)) {
260-
return $this->saveTranslations();
261-
}
262-
255+
if ($this->exists && ! $this->isDirty()) {
256+
// If $this->exists and not dirty, parent::save() skips saving and returns
257+
// false. So we have to save the translations
258+
if ($this->fireModelEvent('saving') === false) {
263259
return false;
264-
} else {
265-
// If $this->exists and not dirty, parent::save() skips saving and returns
266-
// false. So we have to save the translations
267-
if ($this->fireModelEvent('saving') === false) {
268-
return false;
269-
}
270-
271-
if ($saved = $this->saveTranslations()) {
272-
$this->fireModelEvent('saved', false);
273-
$this->fireModelEvent('updated', false);
274-
}
260+
}
275261

276-
return $saved;
262+
if ($saved = $this->saveTranslations()) {
263+
$this->fireModelEvent('saved', false);
264+
$this->fireModelEvent('updated', false);
277265
}
278-
} elseif (parent::save($options)) {
279-
// We save the translations only if the instance is saved in the database.
266+
267+
return $saved;
268+
}
269+
270+
// We save the translations only if the instance is saved in the database.
271+
if (parent::save($options)) {
280272
return $this->saveTranslations();
281273
}
282274

@@ -452,6 +444,11 @@ protected function getLocaleSeparator()
452444
protected function saveTranslations()
453445
{
454446
$saved = true;
447+
448+
if (! $this->relationLoaded('translations')) {
449+
return $saved;
450+
}
451+
455452
foreach ($this->translations as $translation) {
456453
if ($saved && $this->isTranslationDirty($translation)) {
457454
if (! empty($connectionName = $this->getConnectionName())) {

tests/TranslatableTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,29 @@ public function test_it_saves_translations_with_mutator()
127127
$this->assertEquals('5678', $translation->name);
128128
}
129129

130+
public function test_it_does_not_lazy_load_translations_when_updating_non_translated_attributes()
131+
{
132+
DB::enableQueryLog();
133+
134+
$country = Country::create(['code' => 'be']);
135+
$this->assertFalse($country->relationLoaded('translations'));
136+
$this->assertCount(1, DB::getQueryLog());
137+
138+
DB::flushQueryLog();
139+
140+
$country->update(['code' => 'de']);
141+
$this->assertFalse($country->relationLoaded('translations'));
142+
$this->assertCount(1, DB::getQueryLog());
143+
144+
DB::flushQueryLog();
145+
146+
$country->update(['name' => 'Germany']);
147+
$this->assertTrue($country->relationLoaded('translations'));
148+
$this->assertCount(2, DB::getQueryLog());
149+
150+
DB::disableQueryLog();
151+
}
152+
130153
public function test_it_uses_default_locale_to_return_translations()
131154
{
132155
$country = Country::whereCode('gr')->first();

0 commit comments

Comments
 (0)