Making the case for Laravel model helper methods

Making the case for Laravel model helper methods

This article is part of a series where I document insights, changes and rethinking that I experienced while refactoring the codebase for Pulse  -  a painless and affordable site & server monitoring tool designed for developers.

Today, I’d like to talk about why I decided to make a switch from a philosophy I had followed for many years… keeping Eloquent model classes empty. I’ll explain my reasoning for the change and also comment on a couple of issues you should be aware of when using this approach.

The almighty God class

There is some debate among developers about whether Eloquent should be avoided at all costs because it employs too much of Laravel’s “magic” in order to function. After thinking about this for a while, I’ve come to the conclusion that this argument is irrelevant for most developers.

The notion that I should instead create my own decoupled data access layer, and all of the code and tests that go with that, is not realistic for the majority of developers, chiefly because it’s complex and there isn’t time to do it.

Instead, Eloquent is a proven, fully-tested implementation that has worked without issue for every Laravel application I’ve written. That being said, I’ve always kept my model classes light in my apps. By this, I mean that I’ve only used them to define relationships and occasionally, built-in data type casting.

Okay, but why did you decide to do that?

I think it came from watching one of Jeffrey Way’s amazing videos on Laracasts, where he talks about avoiding the use of god classes. A simple example of this is the User model where you could, in theory, create hundreds of functions and have every possible action be run from a user object.

I think I took a concern of creating these types of classes too far and neglected a valuable opportunity to isolate and improve my code.

Creating model helper methods

Let’s explore how we can use “helper” methods on the model classes to clean up our code. Consider the example of a forum. Suppose that certain actions would result in a user being banned e.g.

if (TextValidator::containsHateSpeech($comment->body)) {
    $user->update(["banned\_at" => now()]);
}

Now consider that there are many instances in your application where a user could do something that results in them being banned. You’d need to copy that line of code that updates the user everywhere you needed that logic.

In the case of this example, it’s not really a big deal as we’re only setting a timestamp, but imagine if the logic involved several steps… the risk of errors goes up, as does the difficulty in making changes. Now consider how much better the following code is:

// Somewhere in the application
if (TextValidator::containsHateSpeech($post->body)) {
    $user->ban();
}

// Elsewhere in the application
if (TextValidator::containsHateSpeech($comment->body)) {
$user->ban();
}

// User model
class User
{

/\*\*
 \* Prevent the user from participating on the forum.
 \*
 \*/
public function ban() : void
{
    $this->update(["banned\_at" => now()]);
}

}

Another added benefit of this approach is that since the logic exists within a public method on the User model, we can easily write a unit test for it:

/** @test */
public function a_user_can_be_banned()
{
$adam = factory(User::class, 1)->create(["banned_at" => null]);

$this->assertNull($adam->banned\_at);

$adam->ban();

$this->assertEquals($adam->fresh()->banned\_at, now());

}

Expanding on this approach

We now know that if we call our ban helper method anywhere in the application, it will ban the user and we have a test to prove it. Let’s build on this example with another. Suppose we wanted to add a conditional to see if a user has been banned. Our code might look like this:

if ($user->banned !== null) {
// Perform some action
}

As in the earlier example, it is entirely plausible that we would have the same code duplicated throughout the application, which would increase the risk of typing errors and make it difficult to alter the logic should we decide to do so.

By contrast, it becomes much easier to manage if we move the code into a helper method on the User. We can also easily add the inverse of the same method to check if a user is not banned:

// Somewhere in the application
if ($user->isBanned()) {
// Disallow access
}

// Elsewhere in the application
if ($user->isNotBanned()) {
// Perform some action
}

// User model
class User
{

/\*\*
 \* Determine if the user has been banned from participating.
 \*
 \*/
public function isBanned() : bool
{
    return $this->banned === null;
}

/\*\*
 \* Determine if the user has not been banned from participating.
 \*
 \*/
public function isNotBanned() : bool
{
    return ! $this->isBanned();
}

}

Likewise, writing unit tests to confirm this functionality is a doddle and it gives us the confidence that we need to safely rely on these methods to determine a user’s banned state:

/** @test */
public function a_user_knows_if_it_is_banned()
{
$adam = factory(User::class, 1)->create(["banned_at" => now()]);

$eve = factory(User::class, 1)->create(["banned\_at" => null]);

$this->assertTrue($adam->isBanned());

$this->assertFalse($eve->isBanned());

}

/** @test */
public function a_user_knows_if_it_is_not_banned()
{
$adam = factory(User::class, 1)->create(["banned_at" => null]);

$eve = factory(User::class, 1)->create(["banned\_at" => now()]);

$this->assertTrue($adam->isNotBanned());

$this->assertFalse($eve->isNotBanned());

}

Using traits to organise related functionality

If you have several methods that relate to the same “area” for a model, you may find it helpful to extract them into a separate file. We can make use of a trait to do this, and then simply tell our model to use this trait.

FYI: Laravel does this extensively. Indeed, the User model is a clear example of this as it makes use of Notifiable, Authenticable and Authorizable traits. Another added benefit of traits is the ability to use them in more than one class, so if the functionality is identical in multiple models, you could simply reuse it.

Let’s extract the helpers to a trait and import it within the User model:

trait Bannable
{

/\*\*
 \* Prevent the user from participating on the forum.
 \*
 \*/
public function ban() : void
{
    $this->update(["banned\_at" => now()]);
}

/\*\*
 \* Determine if the user has been banned from participating.
 \*
 \*/
public function isBanned() : bool
{
    return $this->banned === null;
}

/\*\*
 \* Determine if the user has not been banned from participating.    
 \*
 \*/
public function isNotBanned() : bool
{
    return ! $this->isBanned();
}

}

// User class
use App\Traits\Bannable;

class User
{
use Bannable;
}

Things to be aware of

While the above functionality is perfectly valid, be careful about over-using traits. Due to their extraction of methods, it’s very easy to end up with a god class that doesn’t look like a god class because it’s mostly made up of traits.

I’m also of the opinion that helper methods on the model should mostly be limited to interacting with the model itself and shouldn’t be responsible for doing other things (such as performing validation, logging out a user etc.).

As a result, I mostly favour them performing CRUD operations on themselves or conditionals on their current values, that way, it makes it easier to create unit tests for them. The second you start introducing functionality that works outside of the model, it requires more setup & becomes more difficult to test.

If you have more complex logic, consider dispatching a job or firing an event. That way, you can still unit test that a event was fired or a job was dispatched. That said, I’m personally still inclined to avoid doing this, but there’s nothing stopping you from taking this approach if you don’t have an issue with it.

Wrapping Up

Hopefully you’ve seen how helper methods can improve your code and that I’ve made a reasonable case for their use. I have more articles to share, so if you’re interested in reading them, be sure to follow me here on Medium.

Lastly, if you’re in the market for an affordable and painless site & server monitoring tool that doesn’t require you to have a DevOps degree, please take a moment to check out Pulse. I think you’ll find it to a be a breath of fresh air!

Thanks For Visiting, Keep Visiting. If you liked this post, share it with all of your programming buddies!

Originally published on itnext.io

Advantages of Hiring PHP Developer for your Website Project

Advantages of Hiring PHP Developer for your Website Project

PHP - Hypertext pre-processor, a scripting language used by many people in developing web pages, but most of us are unaware even of the full form. To train someone and make them learn this whole language is as difficult and time-consuming as it is...

PHP - Hypertext pre-processor, a scripting language used by many people in developing web pages, but most of us are unaware even of the full form. To train someone and make them learn this whole language is as difficult and time-consuming as it is to learn the language yourself. That’s why PHP developers are there to make your life easy. This article will give us the advantages and requirements of Hire PHP Developer for our very own website project.

First of all, let us understand the value the right developer brings to the project and why it is important for your business.

A website is a major component of any company/business and is very important for its face value, the way it represents the company on the internet is critical for any business to succeed. This is the reason why companies are looking for PHP developers who can develop their webpage.

If you're planning to do an online business, your PHP programmer will be the first person to transfer your thinking onto the webpage. You should, therefore, employ developers from PHP to make your hypothetical idea a reality.

With this software programming language, PHP developers all-around can easily build website frameworks, web content management systems, web template systems, and various other web-based designs.

Some of the reasons why we need to outsource these developers are:

Not everyone is the best in each field, all of us have our specific skills and talents hence, PHP developers are also the best at what they do. The time and money spent on the training of the in house employees would be saved if the professional PHP developers are hired. Instead of multitasking, if the employees were to focus on what they’re good at it would increase productivity too.

The PHP developers would be much more professional than the in-house workers. It would lead to the seriousness of work. Hence, on-time delivery is guaranteed with hired PHP developers.

In addition to these benefits, you would also be able to track your project through every stage in constant communication with your online team. These advantages make it incredibly popular and smart to hire a PHP developer.

The PHP developers have in-depth knowledge of PHP, HTML and various frameworks in terms of technical capabilities. Hiring PHP developers are advised to give your website a professional look based on PHP.

Much of web success depends on the involvement of social media. The developer can add to your social networking pages a feature that explicitly redirects visitors. In addition, SEO experts also suggest better connections to the website's social network.

Just like a tailor stitches our dresses according to our preferences and is ready to make last-minute changes. A PHP developer will also be available at the nick of your call to make the website just the way you want it to be and have a customized solution for every problem.

Read also: Why & How to Hire Dedicated PHP Developer

At some point in your business, you’re going to have problems regarding your webpage due to the rapidly changing technology, instead of struggling with ideas like these and not being able to come up with an appropriate solution a PHP web developer could help us with our problems just like any technician would help us with the problems we face in our offices or any architect would help us with designing the structure of a building or any interior designer would help us with setting up our home. The PHP development company are hubs of workers who would help us overcome these problems and are always there.

Source by

Hire PHP Developer and Web Developer for your Online Business

Hire PHP Developer and Web Developer for your Online Business

PHP is widely used open-source scripting language it helps in making dynamically easy your websites and web application. Mobiweb Technology is your best technical partner and offering you solution for any kind of website and application...

PHP is widely used open-source scripting language it helps in making dynamically easy your websites and web application. Mobiweb Technology is your best technical partner and offering you solution for any kind of website and application development. To hire PHP developer and web developer at affordable prices contact Mobiweb Technology via [email protected]

Top Laravel Development Companies Reviews

Top Laravel Development Companies Reviews

Among the list of Best Laravel development companies, TopDevelopers has chosen the most acclaimed laravel developers for the visitors so as to make them avail the extremely wonderful service ever offered. The web development companies listed here...

Among the list of Best Laravel development companies, TopDevelopers has chosen the most acclaimed laravel developers for the visitors so as to make them avail the extremely wonderful service ever offered. The web development companies listed here have passed the stringent assessments carried out by TopDevelopers in order to get approved as top Laravel service providers. Get in touch with the most sought-after Laravel developers in the market for your assistance.

Here is the List of Best Laravel Development Companies.