Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

abdobargush's avatar

What is the best practice for using traits?

Hello everyone, I've several models that shares thumbnail functionality, so extracted it to a trait and used it like this, I think it's kinda clear and can easily be documented

namespace App\Traits;

/**
 * Add Thumnial functionality to models
 */
trait ThumbnailTrait
{
	private function setThumbnail(?string $value, string $directory, array $size) : void
	{
		// ...
	}
	
	private function getThumbnail(?string $value, string $default) : string
	{
		// ...
	}

}
namespace App\Models;

class Tool extends Model
{
	use \App\Traits\ThumbnailTrait;

	public function setThumbnailAttribute($value)
	{
		$this->setThumbnail($value, 'tools', [256, 256]);
	}

	public function getThumbnailAttribute($value)
	{
		return $this->getThumbnail($value, 'images/[email protected]');
	}
}

but I was thinking that it may be used with properties to alter traits like the following

class Tool extends Model
{
	use \App\Traits\ThumbnailTrait;

	protected $thumbnail = [
		'default' => 'images/[email protected]',
		'directory' => 'tools',
		'size' =>  [256, 256]
	];
}

then rename the trait functions to setThumbnailAttribute and getThumbnailAttribute and make then access the property directly with $this keyword without additional calls in the model

I'm just wondering what is the better way to do it, or if there is a best practice I'm not aware of?

0 likes
5 replies
fylzero's avatar

@abdobargush I would maybe do this as a polymorphic relationship rather than how you have it as a trait.

With Polymorph you could have a model called Thumbnail and a table for thumbnails that stores the thumbnail with the Model class it belongs to. Then just reference Tool::first()->thumbnail->size, etc.

https://laravel.com/docs/8.x/eloquent-relationships#polymorphic-relationships

Highly recommend this Laravel Daily course for explaining polymorphic relationships, if you've never used them. https://laraveldaily.teachable.com/p/laravel-eloquent-expert-level

2 likes
abdobargush's avatar

@fylzero Thank you for bringing up polymorphic relationship, I imagine it would be better approach if I needed more advanced thumbnail functionality as it adds complexity on the database level.

In my application every resource will have only one thumbnail and I don't need to store any additional data associated with it, size and directory are only used during the upload.

fylzero's avatar

@abdobargush This is actually the perfect case for a polymorphic relationship. It doesn't add much database complexity. In fact it should simplify things quite a bit as you'll only need a single table instead of a column on multiple tables to drive this. You should really look into / consider this approach.

2 likes
martinbean's avatar

@abdobargush Traits are a language construct. It’s like asking what the “best practice” is for classes. There aren’t “best practices”; you just use the language features for what they’re intended for.

Traits are used to overcome PHP’s lack of multiple inheritance, and to be able to re-share code between classes. Now, do you models need this code sharing? Or is it functionality that could be wrapped up in a class of its own?

1 like
abdobargush's avatar

Thank you @martinbean, I think I'm getting your point here. Yes, it can be wrapped in a class of its own. I thought of using trait as a code that can be reused by several classes.

Please or to participate in this conversation.