Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add trait with multi-column support with tests #65

Merged
merged 14 commits into from
Aug 28, 2020
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Schema::table('your_models', function (Blueprint $table) {

### Preparing the model

In order to work with the schemaless attributes you'll need to add a cast, an accessor and a scope on your model. Here's an example of what you need to add if you've chosen `extra_attributes` as your column name.
In order to work with the schemaless attributes you'll need to add a cast, an accessor and a scopes on your model. Here's an example of what you need to add if you've chosen `extra_attributes` as your column name.

```php
use Illuminate\Database\Eloquent\Model;
Expand Down Expand Up @@ -106,6 +106,43 @@ class TestModel extends Model
}
```

If you need support for multiple schemaless columns on a single model, you should use `SchemalessAttributesTrait` trait. Here's an example of what you need to add if you've chosen `extra_attributes, other_extra_attributes` as your column names.

```php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Spatie\SchemalessAttributes\SchemalessAttributes;
use Spatie\SchemalessAttributes\SchemalessAttributesTrait;

class TestModel extends Model
{
use SchemalessAttributesTrait;

// ...

/**
* @var array
*/
protected $schemalessAttributes = [
'extra_attributes',
'other_extra_attributes',
];

public function scopeWithExtraAttributes(): Builder
{
return SchemalessAttributes::scopeWithSchemalessAttributes('extra_attributes');
}

public function scopeWithOtherExtraAttributes(): Builder
{
return SchemalessAttributes::scopeWithSchemalessAttributes('other_extra_attributes');
}

// ...
}
```


If you want to reuse this behaviour across multiple models you could opt to put the function in a trait of your own. Here's what that trait could look like:

```php
Expand Down
64 changes: 64 additions & 0 deletions src/SchemalessAttributesTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Spatie\SchemalessAttributes;

use Illuminate\Support\Collection;
use Illuminate\Support\Str;

/**
* @property array $schemalessAttributes
*
* @mixin Collection
*/
trait SchemalessAttributesTrait
{
/**
* @var
*/
private $initializeSchemalessAttributesTrait;

/**
* Get the casts array.
*
* @return array
*/
public function getCasts()
{
if (Str::startsWith(app()->version(), '5.6')) {
freekmurze marked this conversation as resolved.
Show resolved Hide resolved
if (! $this->initializeSchemalessAttributesTrait) {
$this->initializeSchemalessAttributesTrait();
$this->initializeSchemalessAttributesTrait = true;
}
}

return parent::getCasts();
}

public function initializeSchemalessAttributesTrait()
{
foreach ($this->getSchemalessAttributes() as $attribute) {
$this->casts[$attribute] = 'array';
}
}

/**
* @return array
*/
public function getSchemalessAttributes()
{
return isset($this->schemalessAttributes) ? $this->schemalessAttributes : [];
}
freekmurze marked this conversation as resolved.
Show resolved Hide resolved

/**
* @param $key
* @return mixed|SchemalessAttributes
*/
public function __get($key)
{
if (in_array($key, $this->getSchemalessAttributes())) {
return SchemalessAttributes::createForModel($this, $key);
}

return parent::__get($key);
}
}
46 changes: 46 additions & 0 deletions tests/SchemalessAttributesTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Spatie\SchemalessAttributes\Tests;

class SchemalessAttributesTraitTest extends TestCase
{
/** @var \Spatie\SchemalessAttributes\Tests\TestModelUsedTrait */
protected $testModel;

public function setUp(): void
{
parent::setUp();

$this->testModel = new TestModelUsedTrait();
}

/** @test */
public function schemaless_attributes_cast_as_array_initialize_schemaless_attributes_trait()
{
$this->assertTrue($this->testModel->hasCast('schemaless_attributes', 'array'));
}

/** @test */
public function other_schemaless_attributes_cast_as_array_initialize_schemaless_attributes_trait()
{
$this->assertTrue($this->testModel->hasCast('other_schemaless_attributes', 'array'));
}

/** @test */
public function test_get_schemaless_attributes()
{
$this->assertEquals(['schemaless_attributes', 'other_schemaless_attributes'], $this->testModel->getSchemalessAttributes());
}

/** @test */
public function test_get()
{
$this->assertNull($this->testModel->schemaless_attributes->name);
}

/** @test */
public function test_parent_get()
{
$this->assertNull($this->testModel->not_existing_schemaless);
}
}
18 changes: 18 additions & 0 deletions tests/TestModelUsedTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Spatie\SchemalessAttributes\Tests;

use Illuminate\Database\Eloquent\Model;
use Spatie\SchemalessAttributes\SchemalessAttributesTrait;

class TestModelUsedTrait extends Model
{
use SchemalessAttributesTrait;

public $incrementing = false;

public $schemalessAttributes = [
'schemaless_attributes',
'other_schemaless_attributes',
];
}