martinbean

martinbean

Senior Developer at Visualsoft Ltd

Newcastle upon Tyne, UK

Member Since 4 Years Ago

Experience Points 450,935
Experience
Level
Lessons Completed 441
Lessons
Completed
Best Reply Awards 618
Best Answer
Awards
  • Start Your Engines Achievement

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • First Thousand Achievement

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • One Year Member Achievement

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • Two Year Member Achievement

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • Three Year Member Achievement

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • Four Year Member Achievement

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • Five Year Member Achievement

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • School In Session Achievement

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • Welcome To The Community Achievement

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • Full Time Learner Achievement

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • Pay It Forward Achievement

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • Subscriber Achievement

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • Lifer Achievement

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • Laracasts Evangelist Achievement

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • Chatty Cathy Achievement

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • Laracasts Veteran Achievement

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • Ten Thousand Strong Achievement

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • Laracasts Master Achievement

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • Laracasts Tutor Achievement

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • Laracasts Sensei Achievement

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • Top 50 Achievement

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

12 Nov
1 day ago

martinbean left a reply on Using A Policy Class Without Passing Through The Model

@alex-smith I don’t understand where you’re calling this? You should have a User model and then check if that has a profile relation.

martinbean left a reply on Using A Policy Class Without Passing Through The Model

@alex-smith It sounds like you’re just checking whether a given user can create a profile then, which would correspond to the create() method of a ProfilePolicy class:

class ProfilePolicy
{
    public function create(User $user)
    {
        // Only allow users without a profile to create a profile
        return $user->profile()->doesNotExist();
    }
}

Your controller should have a valid user injected through route–model binding, removing the need to check the slug:

Route::bind('{userSlug}', function ($slug) {
    return User::where('slug', '=', $slug)->firstOrFail();
});

Route::get('users/{userSlug}/profiles/create', '[email protected]');
class ProfileController extends Controller
{
    public function __construct()
    {
        return $this->authorizeResource(Profile::class, 'userSlug');
    }

    public function create(User $user)
    {
        return view('profile.create', compact('user'));
    }

    public function store(CreateProfileRequest $request, User $user)
    {
        $profile = $user->profile()->create($request->validated());

        // Redirect somewhere
    }
}
09 Nov
4 days ago

martinbean left a reply on Model Self Instantiating Via Factory-like Static Methods

@HECTORORDONEZ - If you wanted to test the createOrderWithDiscount() method, then you’d had a unit test for your OrderService class, no?

martinbean left a reply on Security In Routes

@timgavin I don’t know what you mean by “put the route first”, but when defining route groups you can define prefixes and middleware at the same time:

Route::middleware('role:user')->prefix('account')->group(function () {
    // Routes
});

martinbean left a reply on Using A Policy Class Without Passing Through The Model

@alex-smith Policies are meant to work with models.

Looking at your example, it’s hard to follow what you’re trying to accomplish. What slug are you checking when a user is attempting to create a “profile”?

martinbean left a reply on Login Event

@nialldorgan I don’t follow. If you overriding the controller method that fired that method, then you’ll need to remember to manually fire it yourself.

martinbean left a reply on Model Self Instantiating Via Factory-like Static Methods

@hectorordonez I’m not sure what you’re after? It’s testing a method on a class is doing what it’s meant to. So what’s the issue?

martinbean left a reply on Model Self Instantiating Via Factory-like Static Methods

@HectorOrdonez I use Laravel’s RefreshDatabase trait:

class OrderTest extends TestCase
{
    public function testCanCreateOrderFromProduct()
    {
        $product = factory(Product::class)->create();

        $order = Order::forProduct($product);

        $this->assertDatabaseHas('orders', [
            'id' => $order->getKey(),
            'product_id' => $product->getKey(),
        ]);
    }
}

martinbean left a reply on Model Self Instantiating Via Factory-like Static Methods

models should not know how to build themselves, and I would definitely put that kind of logic in a repository

@hectorordonez A repository shouldn’t know how to build models. The Repository pattern, as originally defined, was to offer a collection-like interface to objects without being concerned where or how those objects were stored. Objects are then retrieved, with optionally specifying criteria to filter the objects to be returned.

Personally, I don’t mind static methods for creating models. For me…

Order::forProduct($product)

…is terser, easier to read, and easier to reason about than something like:

(new OrderRepository)->createFromProduct($product);

I’ve in fact done something similar in a project recently, where my `Ord model has the following methods:

  • Order::fromCheckout()
  • Order::fromReservation()

martinbean left a reply on How To Handle A Dummy User To Replace A User?

@shadrix You can update the user’s name to “Deleted User” or similar and then soft-delete the record.

To handle relationships in Eloquent models, you can define a “default” model:

public function user()
{
    return $this->belongsTo(User::class)
                ->withDefault(['name' => 'Default User']);
}

martinbean left a reply on Love The New Interface

@maverickchan Are you copying the other “love the new interface” threads? This is NOT cool, man!

martinbean left a reply on Trying To Use Moment.js

@maverickchan I’ve wrote plenty of replies on this forum. I think if I were a serial “answer-copier” then it’d have been flagged before.

I didn’t “steal” your answer and I’ve apologised.

martinbean left a reply on Trying To Use Moment.js

@MaverickChan It wasn’t intentional. I skimmed the thread and replied from my phone this morning on the way to work. Sorry if you think I was copying you.

martinbean left a reply on Table.ajax.url

@davy_yg I think you need to read some tutorials on JavaScript. The first example was just string concatenation.

martinbean left a reply on Trying To Use Moment.js

@abdulaziz Import moment, and then use it in computed properties:

<template>
  <div>
    <p>{{ formattedDate }}</p>
  </div>
</template>

<script>
  import moment from 'moment';

  export default {
    computed: {
      formattedDate() {
        return moment(this.givenDate).format('YYYY');
      }
    },
    //
  }
</script>
08 Nov
5 days ago

martinbean left a reply on How To Cache The Whole Page For Lightning Fast Page Loads.

@mostafalaravel You have lots of options for caching. You can either do it application-side and use middleware to cache the response, or use something such as Varnish that sits on your server and returns cached responses without even touching your application.

martinbean left a reply on Are Sessions Useless If An App Is Ajax Based

@skycoder For API routes, you usually wouldn’t use sessions; instead you’d use a stateless authentication mechanism such as an API token to authenticate the user making the request.

When you know the user, you can then perform authorisation checks (i.e. checking a user is requesting a resource or “part” of your site that they’re allowed to). If a user is trying to access an endpoint they shouldn’t have access to, you should return a 403 Forbidden response and have your Vue components interpret that and show an appropriate error message.

martinbean left a reply on Need Advice On Genealogy Feature In Existing Site

@tommy001 If you’re wanting to build a family tree, you might want to look at a graph database such as neo4j.

martinbean left a reply on Dynamically Changing The Value Of A Checkbox Depending On The Click Status

@patwan Instead, just have a hidden input with the same name but a value of 0. When you submit the form, if the checkbox (with the same name and a value of 1) is not clicked, then 0 will be submitted. If the checkbox is checked, then its value (1) will be submitted.

<input type="hidden" name="some_name" value="0" />

<input type="checkbox" name="some_name" value="1" />
07 Nov
6 days ago

martinbean left a reply on Please Bring Back The Older Laracasts Design

@mo7sin That would tally, as I’m GMT+0.

martinbean left a reply on Please Bring Back The Older Laracasts Design

@jeffreyway I can report the same, too. Whenever someone replies to a topic, it says it was 5 hours ago for me, so suggests it’s a timezone issue.

martinbean left a reply on Upgraded To Mojave, Homestead Not Working

@mike_sa Have you tried doing what the error message says and installing version 5.2 of VirtualBox? I’m running Mojave, and have VirtualBox 5.2.x installed and it works fine with Homestead.

martinbean started a new conversation School In Session Badge Missing?

@JeffreyWay On my profile page there’s a badge for “School in Session” and the description says it’s awarded when a series is fully completed on Laracasts.

I’m sure in four years I’ve completed at least one full series?

martinbean left a reply on Return Record Based On Relationship Subquery

@browntown You can add another whereHas() portion to the query to find trees belonging to a specific estimate:

$trees = Tree::whereHas('treatment', function ($query) {
    $query->where('id', '=', $someTreatmentId);
})->whereHas('estimates', function ($query) {
    $query->where('id', '=', $someEstimateId);
})->get();

martinbean left a reply on Homestead Question, About Port 3306/33060

@ArneDB It’s because Homestead runs inside a virtual machine. MySQL lives in that virtual machine, as does you website, so your .env file should contain `DB_PORT=33. You won’t be able to run Artisan from your Mac/PC though, because it is “outside” of the Homestead, which is why if you want to connect to your database outside of Homestead (say, in Sequel Pro), you need to use port 33060.

martinbean left a reply on Please Bring Back The Older Laracasts Design

You can please some of the people all of the time, you can please all of the people some of the time, but you can’t please all the people all of the time.

martinbean left a reply on Best Way To Use Vue,laravel And Bootstrap

is that Vue should not be running at the same time than Jquery(apparently due to conflicts)

@Boubou Where have you read that? As Vue and jQuery run quite happily together.

martinbean left a reply on Joining Other Table In Second Table Laravel 5.6

@Ramzkie Looking at your tables, a User has one EmployeeProfile, and an EmployeeProfile belongs to many Jobs.

martinbean left a reply on Return Record Based On Relationship Subquery

@browntown Instead of going through the Estimate model, go through the Tree model. You want trees, that’s the model you start with.

Your query would then look something like this:

$trees = Tree::whereHas('treatment', function ($query) {
    $query->where('id', '=', $someTreatmentId);
})->get();

This will get you all Tree models that have a related Treatment model with an ID of $someTreatmentId.

martinbean left a reply on Am I Safe To Not Use A Middleware On My Controller Methods If I Use Auth For Every Query?

@Corbin Security is never something you should be asking, “Would I be OK if I just did…”

It’s better to have too much security than too little!

martinbean left a reply on Joining Other Table In Second Table Laravel 5.6

@Ramzkie Instead of manually creating queries like this, I’d create proper Eloquent models representing the entities in the application, and establish relationships between them. It’s going to make your application’s logic much easier to reason about.

06 Nov
1 week ago

martinbean left a reply on Using ViewComposers When Each View Is Made Up Of Multiple Templates

@thebigk It sounds like you need to re-think how you’re injecting data into your views.

What data is your view composer injecting into the reply partial? Is it not something that can be eager-loaded in the query to get replies itself, rather than delegating to a view composer?

martinbean left a reply on Redirect To A View From Api

@James_Moore A RESTful API shouldn’t return a redirect or a “view”; it should return an appropriate status code and ideally a representation of the newly-created resource.

If you’re creating resources, you should send a 201 Created status, and also include a Location HTTP header that is the URL of where the user can find the newly-created resource. This header’s value is where you want to redirect to.

If you’re using Axios to make AJAX requests, then that would look something like this:

axios.post(url, data).then(response => {
    window.location.href = response.headers.location;
});

martinbean left a reply on How Would You Clean This Up?

@behnampmdg3 First, I’d create a StripeServiceProvider class and set the secret key there so you don’t have to do it before every interaction with Stripe:

use Stripe\Stripe;

class StripeServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Stripe::setApiKey($this->app['config']['services.stripe.secret']);
    }
}

Next, I’d use Cashier to do the actual charging of the user:

class PaymentController extends Controller
{
    public function pay(Request $request)
    {
        $request->user()->charge([
            'currency' => 'usd',
            'source' => $request->input('stripeToken'),
        ]);
    }
}

As an aside, I take care in formatting your code. It’s much easier to reason about if it’s formatted consistently. PSR-2 is the de facto standard when it comes to formatting PHP source code.

05 Nov
1 week ago

martinbean left a reply on Decrypting Data In Eloquent Query

@matttonks11 You could create a class that takes an Eloquent collection instance, spins through each model, and decrypts any encrypted values:

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;

class ModelDecrypter
{
    public function decryptModel(Model $model)
    {
        foreach ($model->getEncryptable() as $attribute) {
            $model->setAttribute($attribute, decrypt($model->getAttribute($attribute)));
        }

        return $model;
    }

    public function decryptCollection(Collection $collection)
    {
        return $collection->map(function (Model $model) {
            return $this->decryptModel($model);
        });
    }
}
$clientData = $client->with('groups:id,name')
            ->select('clients.id','clients.forename', 'clients.surname', 'clients.mobile', 'clients.email', 'clients.created_at')->latest();

$clientData = (new ModelDecrypter)->decryptCollection($clientData);

return datatables()->of($clientData)->toJson();

martinbean left a reply on Why Can't \File::put Return False, Though It Relies On File_put_contents?

@halloei I don’t really know what you’re asking. The put() method will return integer 0, which will evaluate to false if coerced.

martinbean left a reply on Parse Date According To Specific Format

@fogley If you read the <a href="https://carbon.nesbot.com/docs/#api-instantiation"?Carbon docs on instantiation, there’s a createFromFormat() method. The first parameter is the format (as per PHP date function), and the second parameter is the value.

04 Nov
1 week ago

martinbean left a reply on Database Viewer

@braed There are desktop-based applications such as Sequel Pro if you’re using macOS for remotely managing databases.

You shouldn’t really have web-based SQL editors installed on your server as it’s a huge vulnerability if someone were to get access to your server.

02 Nov
1 week ago

martinbean left a reply on Laravel Cache Vs Redis - Real Life Example Please

@Boubou Laravel doesn’t have its own cache, it has a cache component with various drivers, one of which is Redis.

martinbean left a reply on Get Data From Middleware In Controllers? / Limit User To A Limited Resources.

Now I came to think about gates and policies, this might be the perfect use case for that right?

@joveice Well, yes. This is exactly the scenario polices are made for. You should be using a policy to check a user has permission to perform an action on a resource (a resource being a model). You can check teams in the policy:

class PostPolicy
{
    public function update(User $user, Post $post)
    {
        // Check the user belongs to the team that the post belongs to
        return $user->teams->contains($post->team);
    }
}
01 Nov
1 week ago

martinbean left a reply on Can't Use Moment With Vue.js

@afghany Actually import the module instead:

<template>
    <div>
        <p>{{ moment(notification.created_at).fromNow() }}</p>
    </div>
</template>

<script>
    import moment from 'moment';

    export default {
        //
    };
</script>

martinbean left a reply on How To Modify Request Parameters In Controller Using Loop

@jann_20 You could set the key to your question and answer array fields to the current timestamp when creating them:

addQuestionButton.on('click', function (e) {
    // Get current time in seconds
    var now = Date.now();

    // Add a question field
    $el.append('<input name="question[' + now + ']" />');

    // Add an answer field
    $el.append('<input name="answer[' + now + ']" />');
});

Now when you submit your form to your controller, you’ll have two arrays: `questi and `answ, whose keys you can match up by combining them in a collection:

$questions = collect($request->input('questions'));
$answers = collect($request->input('answers'));

$questions = $questions->combine($answers);

foreach ($questions as $question => $answer) {
    //
}
31 Oct
1 week ago

martinbean left a reply on Should Policies Be Used In The Controllers Or Models' Boot Methods?

@g-dot You can simple unit test the policy class:

namespace Tests\Unit\Policies;

use App\Article;
use App\User;
use Tests\TestCase;

class ArticlePolicyTest extends TestCase
{
    public function testUsersCannotCreateArticles()
    {
        $user = factory(User::class)->create();

        $this->assertFalse($user->can('create', Article::class));
    }
}

I, personally, do prefer writing feature tests that tests a user logging in and submitting a form:

namespace Tests\Feature\Articles;

use App\User;
use Tests\Feature\TestCase;

class CreateArticleTest extends TestCase
{
    public function testUserCannotCreateArticles()
    {
        $user = factory(User::class)->create();

        $response = $this->post('/articles', [
            'headline' => 'Test Headline',
            'body' => 'Test body.',
        ]);

        $response->assertForbidden();
    }
}

The reason being, unit testing the policy class tests just that class. It won’t catch if you forget to use your policy in your controller, though. In the second feature test, the testUserCannotCreateArticles() test case would fail if users could unexpectedly create articles. If this was the case, you’d then probably drop into the controller, realise you’ve not added a policy check, and add it. If the test still fails after that, then you would drop into the policy and check the create() method has the condition you expect.

30 Oct
2 weeks ago

martinbean left a reply on How Can Show The Encrypted Password In My View Page As Decrypted Value?

@mousumi_mou You should never display a password in plain text. If you do, it should be consider compromised.

Passwords should also be hashed rather than encrypted. You should never be able to reverse a password. If you can, so can a nefarious user who gains unauthorised access to your application or database.

martinbean left a reply on Can't Install Nova In Production (Heroku)

@Mick79 As a note: it’s probably better to add your authentication credentials as an environment variable rather than hard-coding your email address and password in your application’s composer.json file.

I recently wrote a blog post on how to do this (albeit for Bitbucket private repositories), but the concept is the same—you’d just create an environment variable in your Heroku application called COMPOSER_AUTH with the same JSON blob @ejdelmonico provided.

Blog post: https://martinbean.co.uk/blog/2018/10/16/using-private-repositories-in-composer-on-heroku/#add-environment-variable-to-heroku

29 Oct
2 weeks ago

martinbean left a reply on Laravel API Resource - How To Assign Sequence Number For Each Collection Item?

@Tarasovych You’ll need to prepare the collection before passing it to your resource class:

$users = $users->each(function ($user, $index) {
    $users->sequence_number = $index+1;
});

return UserResource::collection($users);

martinbean left a reply on Where/How To Place Vue Instance And Components

@K3nzie I answered your question.

My question is wheter to place one #app div after the body and having one Vue instance

Yes.