# Make a Model Use Custom Attributes
The admin-defined attributes covered in Create and Use an Attribute only work against entities Krayin knows about โ Leads, Persons, Organizations, Products, Quotes, Warehouses. If your package introduces a new entity (say, Example) and you want admins to attach custom attributes to it, you need to wire that entity into the attribute system.
This page walks through that wiring: register the entity, use the CustomAttribute trait on the model, and persist attribute values from the repository.
For background on packages, see Create a Package. For the admin flow that creates the attributes themselves, see Create and Use an Attribute.
# ๐งฉ What you'll set up
| Piece | Purpose |
|---|---|
attribute_entity_types.php config | Tells Krayin "here's a new entity type that can have attributes". |
CustomAttribute trait on the model | Adds the attribute-value relationships and helpers to the Eloquent model. |
Repository hook into AttributeValueRepository | Saves attribute values whenever the entity is created or updated. |
Once these three are in place, your entity shows up as an option in the Entity Type dropdown on the attribute create form, and any attribute admins add against it is persisted automatically.
# ๐๏ธ 1. Register the entity type
Create a config file in your package telling Krayin about the new entity.
packages/Webkul/Example/src/Config/attribute_entity_types.php
<?php
return [
'examples' => [
'name' => 'Examples',
'repository' => 'Webkul\Example\Repositories\ExampleRepository',
],
];
| Key | Purpose |
|---|---|
Outer key (examples) | Internal identifier for the entity type. |
name | Label shown in the admin's Entity Type dropdown. |
repository | Fully-qualified repository class โ Krayin uses it to look up records by ID. |
# โ๏ธ 2. Merge the config in your service provider
In your package's main service provider, merge this file into Krayin's attribute_entity_types config bag.
public function register(): void
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/attribute_entity_types.php',
'attribute_entity_types',
);
}
After this fires, config('attribute_entity_types') includes your examples entry alongside Krayin's built-in entries.
# ๐งฑ 3. Add the CustomAttribute trait to your model
The trait gives your model the relationships and helpers (attribute_values, accessor magic, etc.) that the rest of the attribute system depends on.
<?php
namespace Webkul\Example\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Attribute\Traits\CustomAttribute;
use Webkul\Example\Contracts\Example as ExampleContract;
class Example extends Model implements ExampleContract
{
use CustomAttribute;
protected $fillable = [
'name',
'slug',
'description',
];
}
The $fillable list only covers the model's native columns โ custom-attribute values live in a separate table and are written through the repository (next step).
# ๐ 4. Persist attribute values from the repository
Krayin ships an AttributeValueRepository whose save($data, $entityId) method writes attribute values for an entity. Call it from your repository's create() and update() so admin-defined attributes are saved alongside the entity itself.
<?php
namespace Webkul\Example\Repositories;
use Webkul\Attribute\Repositories\AttributeValueRepository;
use Webkul\Core\Eloquent\Repository;
class ExampleRepository extends Repository
{
public function __construct(
protected AttributeValueRepository $attributeValueRepository,
\Illuminate\Container\Container $app,
) {
parent::__construct($app);
}
public function model(): string
{
return 'Webkul\Example\Contracts\Example';
}
public function create(array $data)
{
$example = parent::create($data);
$this->attributeValueRepository->save($data, $example->id);
return $example;
}
public function update(array $data, $id, $attribute = 'id')
{
$example = parent::update($data, $id);
$this->attributeValueRepository->save($data, $id);
return $example;
}
}
The exact same call โ $this->attributeValueRepository->save($data, $id) โ covers both new records and updates; the repository figures out which attribute values to insert vs. update internally.
# ๐งช 5. Verify
- Run
php artisan optimize:clearto flush the config cache. - Open the admin, go to Settings โ Attributes โ Create Attribute.
- Open the Entity Type dropdown โ Examples should now be one of the options.
- Create a text attribute against Examples (e.g.
industry). - Open your entity's create form, fill the new field, save.
- Re-open the record โ the value should persist.
If Examples doesn't appear in the dropdown, the most likely cause is the config not being merged. Confirm:
php artisan tinker
>>> config('attribute_entity_types')
You should see your examples key alongside Krayin's built-in entries.
# ๐ Next steps
- Create and Use an Attribute โ the admin flow for creating the attributes that this wiring enables.
- Repository โ deeper coverage of Krayin's repository pattern, useful when extending
ExampleRepositoryfurther. - Events Listeners โ hook
settings.attribute.create.afterto react when admins add new attributes for your entity.