Skip to content

Commit

Permalink
Merge pull request #104 from adamcopley/soft-deletes-fix
Browse files Browse the repository at this point in the history
ensure slugs are still unique if we use soft deletes
  • Loading branch information
AlexVanderbist authored Jun 8, 2019
2 parents 1467323 + aac145d commit eb3b87b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to `laravel-sluggable` will be documented in this file

## 2.1.8 - 2019-04-21

- ensure slugs are still unique when soft deletes are in use on model

## 2.1.7 - 2019-02-26 ❤️

- Add support for Laravel 5.8
Expand Down
20 changes: 17 additions & 3 deletions src/HasSlug.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,24 @@ protected function otherRecordExistsWithSlug(string $slug): bool
$key = $key ?? '0';
}

return static::where($this->slugOptions->slugField, $slug)
$query = static::where($this->slugOptions->slugField, $slug)
->where($this->getKeyName(), '!=', $key)
->withoutGlobalScopes()
->exists();
->withoutGlobalScopes();

if ($this->usesSoftDeletes()) {
$query->withTrashed();
}

return $query->exists();
}

protected function usesSoftDeletes()
{
if (in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this))) {
return true;
}

return false;
}

protected function ensureValidSlugOptions()
Expand Down
11 changes: 11 additions & 0 deletions tests/Integration/HasSlugTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,15 @@ public function getSlugOptions(): SlugOptions
$model->save();
$this->assertEquals('guete-nacht', $model->url);
}

/** @test */
public function it_will_save_a_unique_slug_by_default_even_when_soft_deletes_are_on()
{
TestModelSoftDeletes::create(['name' => 'this is a test', 'deleted_at' => date('Y-m-d h:i:s')]);

foreach (range(1, 10) as $i) {
$model = TestModelSoftDeletes::create(['name' => 'this is a test']);
$this->assertEquals("this-is-a-test-{$i}", $model->url);
}
}
}
8 changes: 8 additions & 0 deletions tests/Integration/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ protected function setUpDatabase(Application $app)
$table->string('other_field')->nullable();
$table->string('url')->nullable();
});

$app['db']->connection()->getSchemaBuilder()->create('test_model_soft_deletes', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->nullable();
$table->string('other_field')->nullable();
$table->string('url')->nullable();
$table->softDeletes();
});
}

protected function initializeDirectory(string $directory)
Expand Down
48 changes: 48 additions & 0 deletions tests/Integration/TestModelSoftDeletes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Spatie\Sluggable\Test\Integration;

use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class TestModelSoftDeletes extends Model
{
use SoftDeletes,
HasSlug;

protected $table = 'test_model_soft_deletes';

protected $guarded = [];

public $timestamps = false;

/**
* Get the options for generating the slug.
*/
public function getSlugOptions() : SlugOptions
{
return $this->slugOptions ?? $this->getDefaultSlugOptions();
}

/**
* Set the options for generating the slug.
*/
public function setSlugOptions(SlugOptions $slugOptions) : self
{
$this->slugOptions = $slugOptions;

return $this;
}

/**
* Get the default slug options used in the tests.
*/
public function getDefaultSlugOptions() : SlugOptions
{
return SlugOptions::create()
->generateSlugsFrom('name')
->saveSlugsTo('url');
}
}

0 comments on commit eb3b87b

Please sign in to comment.