I am working on a blogging application in Laravel 8.
I have a settings
table from which I pull the directory name of the current theme.
class ArticlesController extends Controller {
public $theme_directory;
public function index() {
// Theme _directory
$this->theme_directory = Settings::all()[0]->theme_directory;
// All articles
$articles = Article::all();
return view('themes/' . $this->theme_directory . '/templates/index', ['articles' => $articles]);
}
public function show($slug) {
// Theme _directory
$this->theme_directory = Settings::all()[0]->theme_directory;
// Single article
$article = Article::where('slug', $slug)->first();
return view('themes/' . $this->theme_directory . '/templates/single', ['article' => $article]);
}
}
The problem
A you can see, the line $this->theme_directory = Settings::all()[0]->theme_directory
is repeted in both methods (and would be repeted in others in the same way).
Question
How can I avoid this repetition (and make my code DRY)?
CodePudding user response:
Inheritance approach
Inheritance for a controller would avoid you from repeating it.
abstract class CmsController extends Controller{
protected $themeDirectory;
public function __construct()
{
$this->themeDirectory= Settings::first()->theme_directory ?? null;
}
}
Extend it and you can access it like you have always done.
class ArticlesController extends CmsController
{
public function index() {
dd($this->themeDirectory);
}
}
Trait
Use traits which is partial classes, done by just fetching it, as it is used in different controllers the performance is similar to saving it to an property as it is never reused.
trait Themeable
{
public function getThemeDirectory()
{
return Settings::first()->theme_directory ?? null;
}
}
class ArticlesController extends CmsController
{
use Themeable;
public function index() {
dd($this->getThemeDirectory());
}
}
Static function on model
If your models does not contain to much logic, a static function on models could also be a solution.
class Setting extends model
{
public static function themeDirectory()
{
return static::first()->theme_directory ?? null;
}
}
class ArticlesController extends CmsController
{
use Themeable;
public function index() {
dd(Setting::themeDirectory());
}
}