Roni

Roni

Member Since 4 Years Ago

WINNIPEG, MANITOBA

Experience Points 74,070
Experience Level 15

930 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed 818
Lessons
Completed
Best Reply Awards 5
Best Reply
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.

13 May
1 week ago

Roni started a new conversation Does Mix Have Any Commands For Brotli Compression?

Just reading the tailwindcss docs, now that v 1.0 is out, and they refer to brotli compression. Is there a setting in laravel mix that enables brotli compression? Does anyone know how to roll this out to the server besides checking it off on cloudflare?

19 Mar
2 months ago

Roni started a new conversation Adding Groups Of Assertions To Tests

Hi Guys,

I've been really playing with macro's and focusing a lot on adding different assertions to deal with specific groups of issues, like getting view data and lots of collection assertions or vue assertions, and my Testcase setup() function is getting pretty long.

In the past I've broken this down, by extending TestCase through a hierarchy.

Like adding a DatabaseTestCase Extends DomainTestCase Extends BaseTestCase Extends TestCase the list goes on and then I choose how much functionality I want to include. But if I need function at the top I basically have now included all the functionality that I don't need.

I feel like there is probably a better way to organize this as I continue to add more macros to suit my needs. Is there a way to extract the setup method to run a pipeline of classes which each include a small subset macro's that are really specific and focused, or have those macros stored in traits each having a setup method that injects some specific macros?

Thanks.

06 Mar
2 months ago

Roni left a reply on Eager Loading BelongsTo Relationship

Something to watch out for, I don't have time to test it, but I feel like your method has to be renamed or you need to put in your table and foreign keys on your relationship.

//notice the uppercase
public function productCategory()
    {
        return $this->belongsTo('App\Models\ProductCategory');
    }


I think laravel is looking for a "productcategories" table and not a "product_categories" table, since you have no caps in your relationship name.

It's thrown me for hours before I started writing unit tests for relationships out of the gate.

Here is a simple example of a relationship test you can do write before you create your relationship:

IntakeTest.php

<?php

namespace Tests\Unit\Model\Relationship;

use App\Client;
use App\Intake;
use Tests\DomainTestCase;

class IntakeTest extends DomainTestCase
{
    /** @test */
    public function intake_belongs_to_a_client()
    {
        $client = create(Client::class);
        $intake = create(Intake::class, ['client_id'=> $client->id]);

        $this->assertTrue($client->intake->is($intake));
        $this->assertTrue($client->is($intake->client));

    }
}

Roni left a reply on Session Sharing On Multiple Logged-in Users

What are you using to allow multiple authentications at the same time? Normally your app should guard against this, even a fresh install with wont have this issue.

Please provide a detailed response, with snippets if you wrote it. If not contact the person who wrote the code.

Roni left a reply on Post Vs. Post Json

sorry @bobbybouwmann saw this the same day and it's a perfect answer, I forgot to mark it. Apologies.

26 Feb
2 months ago

Roni left a reply on Using Google Cloud Task In Laravel PHP

you should post this in guides instead

25 Feb
2 months ago

Roni started a new conversation Post Vs. Post Json

Hey this threw for for a crazy loop, so I thought I'd point it out here and maybe get some guidance.

I was writing up a test for my endpoint 'client.store', and in my validation I have a form request object that creates all the validation rules.

Now, in the app I was getting the right results and I know, very evil I was writing the test after the fact, I had changed implementations and hadn't upgraded the test yet.

I wrote what appeared to be the easiest test, and ... the test was failing, even the the app works correctly.

In the app I'm making an axios request to my client.store endpoint with a bunch of data and it throws all the correct errors but when I test it, I asserted the session had errors ... and it didn't.

Here is the test


    /** @test */
    public function a_client_under_care_requires_a_valid_care_facility() {
        $this->basicSignIn(User::first());
        $this->withExceptionHandling()
            ->postJson(route('client.store'),$this->getValidFields([
                'is_under_care' => 1
            ]))
            ->assertSessionHasErrors(['pcf.id', 'pcf.room']);


//which yields
Session is missing expected key [errors].
Failed asserting that false is true.

    }

I was ready to tear out my hair, and for no reason, I decided to change the postJson function to just post.


    /** @test */
    public function a_client_under_care_requires_a_valid_care_facility() {
        $this->basicSignIn(User::first());
        $this->withExceptionHandling()
            ->post(route('client.store'),$this->getValidFields([
                'is_under_care' => 1
            ]))
            ->assertSessionHasErrors(['pcf.id', 'pcf.room']);
    }


//works perfectly!?!?!

Since I am only ever invoking this route with an axios post request with a json payload, I just assumed that postJson was the most similar method. However it seems to bypass validation.

Any ideas? Does this seem odd?

Hope someone can shed some light on this or at least this might save someone an hour of checking every character for a non existent typo.

Roni left a reply on TDD CSRF Mismatch

I'm using a vue turbolinks front end. When a page expires it won't redirect as it's only receiving XHR requests. So I monitor them for 401 or 419 status codes and then redirect manually from the vue page component. After I noticed that and found the solution, I thought i should write a test for it, as it will probably crop up in future work. However I realized that I don't know how to write that test.

I'm sure I can affect headers with the postJson function, I just thought that someone who knows more might already have a solution.

Roni left a reply on Basic Json

@TALINON - Damn that made me laugh out loud at an inappropriate time!

Roni started a new conversation TDD CSRF Mismatch

Hi Guys, I already have the code solution, but it occurs to me that I don't know how to write the test to determine a CSRF mismatch coming from a JSON post request. If anyone knows a quick solution please comment.

Here is what I had thought but I'm not sure how to add in or change the CSRF header:

public function an_expired_session_that_fires_an_ajax_post_request_redirects_back_to_login_route() {
    $this->basicSignIn(User::first());  // a helper function to make sure we are authenticated.
        $this->get(route('client.create'))
            ->assertOk();

    // I need a way to expire the session here, or change the CSRF token

    $this->postJson(route('client.store'), $this->getValidFields())
        ->assertStatus(419);
}

Thanks in advance

Roni started a new conversation Turbolinks / Vue Front End Authentication

@reinink, or anyone who is using this paradigm, when using vue as a front end (referring to this article here: https://reinink.ca/articles/server-side-apps-with-client-side-rendering.) How do you deal with session timeouts?

A full refresh will of course trigger the auth middleware, but if someone was half way done a form for example, and the session ran out, the json post request clearly wont handle the redirect on it's own. In those cases, are you just catching errors and getting turbo links to send you to login page? Are you doing something on each component or are you wrapping you composing your components to contain some sort of axios handler? Any thoughts on the matter are welcome.

Thanks.

15 Feb
3 months ago

Roni left a reply on Access Vue Variables From Slot Data

thanks @digiproduct, I'll check them out, the award is yours once I find it... Cheers

Roni started a new conversation Access Vue Variables From Slot Data

Is there a way to access/update Vue data variable from inside a named slot? Right now I have a vue component working with blade partials in slots, and it would be so convenient if I could have a button that has to be inside the slot, update one of the reactive data variables. Is there a way to emit an event that vue would be listening for from vanilla javascript?

28 Jan
3 months ago

Roni left a reply on Use A Regex Validation ONLY If Another Field Is Missing.

Damn, it took a while to figure this one out, but essentially you need to give the fields the ability to be nullable

return [
         'home_phone' => 'required_without:cell_phone|nullable|sometimes|npa_phone',
         'cell_phone' => 'required_without:home_phone|nullable|sometimes|npa_phone',
      ];

Roni started a new conversation Use A Regex Validation ONLY If Another Field Is Missing.

Hi, I've got a form request, that has a basic requirement.

  1. It needs valid npa phone numbers.
  2. It only needs one phone number even though more than one is asked for.

Right now, I can get either to work, but not both

OPTION 1 Works for requiring only one phone.


 public function rules()
   {
      return [
   
         'cell_phone' => 'required_without:home_phone',
         'home_phone' => 'required_without:cell_phone',
    
      ];
   }

OPTION 2 Works for validating an npa phone number

 public function rules()
   {
      return [
         'cell_phone' => 'npa_phone',
         'home_phone' => 'npa_phone',
    
      ];
   }

NPA is in AppServiceProvider Boot method:

 public function boot()
    {
       Validator::extend('npa_phone', function($attribute, $value, $parameters)
       {
          $attribute = preg_replace('/\D/', '', $attribute);
          $pattern = '~^\(?([2-9][0-9]{2})\)?([2-9](?!11)[0-9]{2})([0-9]{4})$~';
          return preg_match($pattern, $attribute);
       });
    }

What I'm trying to accomplish is the following:

  return [
         'cell_phone' => 'required_without:home_phone|npa_phone',
         'home_phone' => 'required_without:cell_phone|npa_phone',
     
      ];

Any advice appreciated.

Roni left a reply on [Tip] Speed Up Composer

This is a super old thread but the question still comes up. However there is a thread on stack exchange newer which came out in 2016 that makes an INSANE composer difference

6 minutes in my case for a super small Laravel project to 7 seconds.

Link: https://stackoverflow.com/questions/28436237/why-is-php-composer-so-slow#38102206

on macOS mojave here are the commands I did

1. networksetup -listallnetworkservices
2. networksetup -setv6off Wi-Fi 
// turn off all IPV6, this had minor benefit
3. composer config --global repo.packagist composer https://packagist.org
// appears to also have big benefit
4. composer global require hirak/prestissimo
// that is insane, its all explained in the link above

Some Comparisons

[306.1MB/466.64s] Discovered Package: beyondcode/laravel-dump-server Discovered Package: fideloper/proxy Discovered Package: laravel/nexmo-notification-channel Discovered Package: laravel/slack-notification-channel Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nothingworks/blade-svg Discovered Package: nunomaduro/collision Discovered Package: roniestein/quicktools Discovered Package: spatie/laravel-view-models Package manifest generated successfully. [304.7MB/466.65s] Memory usage: 304.66MB (peak: 463.81MB), time: 466.65s

AFTER 3. [306.4MB/43.47s] Discovered Package: beyondcode/laravel-dump-server Discovered Package: fideloper/proxy Discovered Package: laravel/nexmo-notification-channel Discovered Package: laravel/slack-notification-channel Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nothingworks/blade-svg Discovered Package: nunomaduro/collision Discovered Package: roniestein/quicktools Discovered Package: spatie/laravel-view-models Package manifest generated successfully. [305.0MB/43.48s] Memory usage: 304.99MB (peak: 463.67MB), time: 43.48s

AFTER 4. [306.6MB/6.66s] Discovered Package: beyondcode/laravel-dump-server Discovered Package: fideloper/proxy Discovered Package: laravel/nexmo-notification-channel Discovered Package: laravel/slack-notification-channel Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nothingworks/blade-svg Discovered Package: nunomaduro/collision Discovered Package: roniestein/quicktools Discovered Package: spatie/laravel-view-models Package manifest generated successfully. [305.2MB/6.67s] Memory usage: 305.22MB (peak: 463.84MB), time: 6.67s

hopes this saves you from hating/dreading composer update. cheers :)

19 Dec
5 months ago

Roni left a reply on Add Packages To Tests

@d9705996 this is perfect! Thank you!!!!

Roni left a reply on Add Packages To Tests

Looks good, I'll give it a read through and mark this best if I can get through it. Thanks @

18 Dec
5 months ago

Roni started a new conversation Add Packages To Tests

Hi All, I made a nifty little package to make testing / scaffolding a new project easier. It's my first package and it's basically only made for me. Perhaps it might help you learn to write your own small package too.

However, I have no idea how to go about adding tests to a package, and more importantly how to develop a package with TDD.

If anyone knows a good resource for that or has some advice, please let me know.

Thanks,

Here is the package if it helps or just if you are interested.

https://github.com/roni-estein/quicktools

Roni left a reply on Extend A Blade View And Yield In The Same File.

Well lucky I posted here :( I never noticed the missing quote. Too much staring at the screen. So in fact this does all just work. Cheers

Roni started a new conversation Extend A Blade View And Yield In The Same File.

I've been playing with really unifying my code structure to make maintaining different projects a bit less time consuming, so I've been spending some time on structures lately. I always have a bunch of layout files, that eventually get added to the project, and was wondering if I'm approaching this wrong,

I typically find a in resources/layouts a bunch of very similar repeated code. For example:


app-with-nav.blade.php
app-with-nav-single-screen.blade.php
app-without-nav.blade.php
app-without-global-vue.blade.php
the list goes on

These are all almost the same, they'll have a base head section but with some modifier around the @yield('content')

I've been trying to look at having them all do something like extending a middle page, but, so far laravel doesn't like it. Here is an example from a new 5.7 project fresh install:

app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    {{--<link rel="dns-prefetch" href="//fonts.gstatic.com">--}}
    {{--<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">--}}

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    @yield('page-stuff')
</body>
</html>

app-without-nav.blade.php

@extends('layouts.app)

{{-- PRESUMABLY SOMETHING HAPPENS HERE THAT MAKES THIS PAGE DIFFERENT FROM OTHERS BUT NOW DOESN'T NEED TO TOUCH / REPRODUCE ANYTHING OTHERTHAN IT'S SPECIFIC TARGET MATERIAL--}}

@section('page-stuff')
    <div class="something">
        @yield('content')
    </div>
@endsection

Now, if something extends app-without-nav it dies a horrible death.

Idea's are welcome. And organizing schema's appreciated.

12 Dec
5 months ago

Roni left a reply on Using A Global Php Helper Functions When Developing A Package

@jlrdw yeah, it's easier in my opinion after looking at both, instead of wondering where the magic test_path function came from, I used BaseProject::testPath() which I feel is very clear and readable.

Thx

Roni left a reply on Using A Global Php Helper Functions When Developing A Package

Makes sense, I think I'll go with this method, I'll try it out momentarily

11 Dec
5 months ago

Roni left a reply on Using A Global Php Helper Functions When Developing A Package

@cronix, that does work, but seems un-composer-y. However it's better than the ugly static on the service provider. If I can't find a better solution the award is yours. Cheers and thanks for all the help.

Roni left a reply on Using A Global Php Helper Functions When Developing A Package

yeah, putting it in mine, but it still errors out saying it can't find the function. :( I've tried autoload and autoload-dev for the file. I'm looking for some example projects that do it in the mean time.

Roni started a new conversation Using A Global Php Helper Functions When Developing A Package

When in laravel, to add a "helpers.php" to the global scope so you can use it's functions, you can add a line like this to your composer.json


 "autoload": {
        "psr-4": {
            "App\": "app/"
        },
        "files": [
            "app/Helpers/BaseHelpers.php"
        ]
    },


However, when trying to develop a package, I've wanted to make a couple of helper functions to be used in multiple files like function test_path() for example.

When I create the same autoload or autoload-dev entry it can't seem to find the function.

I've resorted to adding it in the service provider as a static function which feels gross in some instances like PackageServiceProvider::test_path('stuff.php');

Is there a way I can create a global function so I can use it in multiple places in the package?

Thanks

05 Dec
5 months ago

Roni left a reply on Developing Packages

@moesaid thx, glad it helped. any chance of an award? I don't sneak them by very often :)

Roni left a reply on Developing Packages

Doing the same thing, look at the wink package, for a really simple package. Source dive it, it's really small yet powerful. https://github.com/writingink/wink Or for a more robust package I would maybe look at something close to what you might want to do. I've been source diving https://github.com/JosephSilber/bouncer, mainly for his structure.

You could also try anything spatie. Look at their smaller packages.

Good luck but start with source diving and read that packages form. Oh and the most helpful thing I've found is go to laracon.net and watch the taylor otwell keynote. It's awesome for laravel but at 43 minutes in he talks about how he develops packages locally, it's awesome and a huge time saver.

04 Dec
5 months ago

Roni left a reply on Composer Assistance For Autoloading A File In A Package

@jlrdw I've been thinking about what you've said perhaps this is an option, I'm not sure about the pros and cons of this as opposed to the require:

https://github.com/JosephSilber/bouncer/blob/master/tests/helpers.php

I think it creates a function only if the function does not exists and limits it to the Tests\ namespace. I might have to rewrite it to work for example in a factory which I believe has no namespace. I'm also not that familiar with adding testing directly in packages. That will be my question for you after I've had a chance to do some research on it this weekend. :)

Roni left a reply on Composer Assistance For Autoloading A File In A Package

@jlrdw , Thanks for the update,There are a couple of reasons.

I'm replacing some functions already widely in use in my projects. I'd like to go back and include the package in them one at a time. But it has some ubiquitous functions. I have a ddf() function that wraps around dd but also tells me the calling function and arguments for example. (I've left one or two in a test suite before and when I was just using dd it took a while to track down the offending file. Since it's a global function used in factories, controllers, tests, I'm not requiring it anywhere.

Other things I'm only using in some places, but again, it just seemed easiest. I thought of making a command to overwrite some of the offending versions of the file, but I thought it might make for a painful transition if make a mistake in how a project was implementing something. This seemed like a really graceful way to transition the code bases, first with a composer update to add the new package and remove the helpers, and then move back forth as I massage out the bigs and differences.

I also want it to be very easy to source dive so on joint projects other can easily adapt to it.

Roni left a reply on Composer Assistance For Autoloading A File In A Package

@jlrdw thanks for the quick response,

One sec, to clarify,

I want to move my helpers.php out of my project and into my package. Right now it IS in my package, but without the require statement, everything fails. Are you saying composer dump autoload should find non namespaced php files and include them globally? I haven't tried it, but it doesn;t make sense to me. What I want to do is remove it from my proejcts as they all have it but there are 20 different version that are each a little different, missing a function or one has a capital letter in a name etc... and I always copy it form place to place.

The package idea of standardizing it and cleaning it and 10-15 other things that I ALWAYS use seems like a great idea. In fact I can't believe I waited until now to do it.

But after testing that theory, I can tell you that for me at least it needs to be required. It just seems like other people have found a way to do it with autoload which I believe would be more maintainable and clearer to another user. Here is an example where someone got it to work. (I haven't tested it. However they also don;t have any namespaces.

https://github.com/djaxho/laravel-cats

Roni started a new conversation Composer Assistance For Autoloading A File In A Package

I've found an ugly solution to this already but i was hoping there was a better one.

I'm working on my first package, it's a time saver for me, but I'll publish it when it's a bit more complete for anyone who might want it. Right now, It simply adds a series of commands and a few files that address quickly starting up a project.

I have a number of functions that I use in global scope in my projects as well. Now in my project I simply add it in composer as follows.


 "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\": "app/"
        },
        "files": [
            "app/Helpers/helpers.php"
        ]
    },


However, if I want my package to include it, much like a global dd() function, I haven't figured that out. I've tried adding a files parameter to the autoload section of the package but it doesn't work. Oddly it doesn't even throw an error if you give it a purposely wrong name.

I've been able to make it work it by adding a require statement in the package service provider. But that seems hackish:


<?php

namespace Package;

require ('Helpers/helpers.php');

use Illuminate\Support\ServiceProvider;

class PackageServiceProvider extends ServiceProvider {

Any Advice welcome

Cheers and thanks.

18 Nov
6 months ago

Roni left a reply on Live Pair Programming

@drfraker that looks AWESOME! I'm so stoked to try it out, I guess its finally time to try out VScode

Roni left a reply on Is There A Way To Make A Form Request From Another Request

Love Taylor Otwell, his video on the laracon.net is so jam packed full of goodies. It gives all the hints about where to look to solve this, but basically you can create one form request from another, since all form requests extend Illuminate\Http\Request, they have a static method called "createFrom"

So you can code something like this to pass on a more specific version of your request:

$questionAForm = QuestionAForm::createFrom($request);
$this-> storeQuestionA($questionAForm, $topic_slug);

Roni left a reply on Is There A Way To Make A Form Request From Another Request

Hi @JeffreyWay, The form seems to still be doing something odd with the timezones. I just posted this and it's 57 min old. Which is weird. Seems like it should be correct or some function of 60 min old.

Roni started a new conversation Is There A Way To Make A Form Request From Another Request

This may be a silly solution and there are others I could already make however I have this route set:

// This won't work unless you add some functionality to the root controller
// but this ins't the question. It's based on some tweets from spatie.be 
// with some adamwathan comment ideas thrown in there.
// just putting this note in, incase any one tries this and breaks their "web.php" 

Route::post('account/topic/{topic_slug}/type/{question_type}/' , TopicQuestionController::at('store'))->name('topic.question.store');

Route::get('account/topic/{topic_slug}/type/{question_type}/create' , TopicQuestionController::at('create'))->name('topic.question.create');


This store lets me respond to all question types, and depending on the "question_type", I would like to make a new form request out of the request data.

  1. simple solution is to just change question type into a hard coded path for example:

Route::post('account/topic/{topic_slug}/type/question-a/' , TopicQuestionAController::at('store'))->name('topic.question.a.store');

Route::post('account/topic/{topic_slug}/type/question-b/' , TopicQuestionBController::at('store'))->name('topic.question.b..store');

//etc ...

But this is a hobby project where I want to push the edge of my knowledge so ...

I have this store method:

public function store(Request $request, $topic_slug, $question_type)
    {
        if($question_type == 'questionA'){
            $this->storeBasicFact($request, $topic_slug);
        }
    }

    public function storeQuestionA(QuestionAForm $form, $topic_slug )
    {
        dd($form);
    }


Now clearly this won't work I'm trying to pass a request object into another differing object even though it extends request. However if I asked for a QuestionAForm, laravel would have autowired it for me in the original store method.

anyone know where laravel does that or how I could implement that middlestep of converting the request to another form request object?

14 Nov
6 months ago

Roni left a reply on Elegant Way To Authorize A Form Request

Thanks @ahmeddabak @mushood, I've used the middleware on route and just in the controller before, but I have never used the actual overwritten form request before which I thought might be a really easy place to put these concerns since it's baked in. I just thought I was missing something.

Thanks for the answers, since you are both correct I'm just picking the first.

13 Nov
6 months ago

Roni started a new conversation Elegant Way To Authorize A Form Request

Hi All, I'm playing with FormRequests and Looking at my first authorization. It feels like there should be a cleaner way and I'm missing something. Is there a better way to accomplish this? It already works.

I'd like to update this topic if, the topic account_id is the same as the $this->account_id which is coming from a form but could come from auth()->user()->account->id or a convenience method i have auth()->accountId().

The problem is that when the authorize function is called, I don't have the topic yet, that gets resolved after as I understand it in the controller. Since I'm not directly calling authorize(), I can't pass it a parameter, so I need to use the string URL

If someone is manipulating this, maybe a malformed ajax request the find method wont find anything, which will trigger an trying to access a member on null, or I could use find or fail and catch a ModelNotFoundException, but they both mean I'm unauthorized. I could just return true and deal with this in the update persisting method once I have the topic passed in, but it's just deferring this to look cleaner and then I have am authorize method that just returns true...

Am I looking at this in the wrong way?


 public function authorize()
    {
        if ($this->isMethod('POST')) return true;

        if ($this->isMethod('PATCH')){

            try{
                $topic = Topic::find($this->segment(2));
                return !! $topic->account_id == $this->account_id;
            }catch (\Exception $e){
//      return false;
                Throw new UnauthorizedException('You Are Not Authorized to Edit this Topic');
            }

        }
    }

Here is the controller


    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(TopicForm $form, Topic $topic)
    {
        $form->update($topic);
    }


The update method in the topic form


    public function update($topic)
    {
        // we could more easily implement authoization here
        // but it seems like I'm missing the point if I
        // do it that way.
        $topic->update($this->input());
    }

Thanks

Roni left a reply on Exists In A Table Validation Issue

@talinon you are the king, I must need yet another coffee.

Roni started a new conversation Exists In A Table Validation Issue

It's Tuesday morning and I'm under the weather, so my brain must be missing something jsut a validation request where my last rule is causing an issue. I need to validate that the incoming account_id is a valid id in the accounts table. I added them rest of the tests just to make sure that data was indeed coming in and in the end the two dumps showing that the ID in the Accounts table was there, and that the input matched the id ( I doubled that first test becuase my dump with a concat made the data look a bit funny and I didn't want to confuse anyone:


 public function rules()
    {
    dump(Account::all()->pluck('id'));
        dump('ACCOUNTS TABLE: '. Account::all()->pluck('id'));
        dump('INPUT ACCOUNT : '. $this->input('account_id'));

        return [
            'name' => 'required',
            'min_age' => 'required|numeric|min:3',
            'requires_group' => '',
            'public_visible' => '',
    // this line is the issue and it looks right to me !
            'account_id' => 'required|numeric|integer|min:1|exists:accounts, id',
        ];
    }


here is the test output


Testing started at 10:13 AM ...
/usr/local/bin/php /Users/roni/code/php/laravel/5.7/pie/vendor/phpunit/phpunit/phpunit --configuration /Users/roni/code/php/laravel/5.7/pie/phpunit.xml --filter "/(::a_valid_topic_can_be_created_in_the_database_by_an_authenticated_user)( .*)?$/" Tests\Feature\Topic\CreateTopicTest /Users/roni/code/php/laravel/5.7/pie/tests/Feature/Topic/CreateTopicTest.php --teamcity
PHPUnit 7.4.3 by Sebastian Bergmann and contributors.

Illuminate\Support\Collection {#1077
  #items: array:1 [
    0 => 1
  ]
}
"ACCOUNTS TABLE: [1]"
"INPUT ACCOUNT : 1"
"Tests\DomainTestCase\errorsArray([])"
"-------------------------------------------"
Illuminate\Support\MessageBag {#1092
  #messages: array:1 [
    "account_id" => array:1 [
      0 => "The selected account id is invalid."
    ]
  ]
  #format: ":message"
}

Process finished with exit code 1

Thanks for any assistance

12 Nov
6 months ago

Roni started a new conversation Visual Issue On Profile Section In Site

Hi @jeffrey_way, on the profile section where is lists your badges, unless your scree size is over xl, the mouse over descriptions on badges on the left and right sides bleed over the edge of the viewport. So on the far left and the far right, first 2-3 on each side the text and background box is cut off.

Clearly not a high priority, but thought I'd let you know.

08 Nov
6 months ago

Roni left a reply on Making Model Macroable

Well Damn Me! You can't the macroable trait because you are overwrittingt he macro's array! Because model IS macroable! I couldn't source dive find where it happens, but I removed everything and the macro's never stopped working.

I hope this saves you a few hours.

Cheers.

Roni started a new conversation Making Model Macroable

Hi, I've found it super helpful under certain circumstances to make model macroable. However I'm finding some drawbacks. I'm hoping someone might have a little deeper knowledge on this.

The only place I use it is in testing, and it's amazingly helpful. When faced with a nasty query, being able to throw the array, table, or collection into a console table printout has been a real go to. Taking what was a much longer process and shrinking it to a minute or two as the information pops out at you.

The main reason for doing this is to have access to the attributes array externally under test that you won't have access to in the actual app. It keeps the app code clean and the testing fast.

However, checking the rest of the test suite showed some conflicts with commands from the builder like "find" or "where", which is kind of a big deal. Has anyone properly implemented Macroable in a non conflicting way?

Here are the files for clarification with some examples, all are properly visible and working, it's not a composer autoload issue.

My Model


namespace App\Helpers;

use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Support\Traits\Macroable;


class Model extends EloquentModel
{

    use Macroable {
        __call as myMacroCall;
    }

    public function __call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->myMacroCall($method, $parameters);
        }

        return parent::__call($method, $parameters);
    }

    protected $guarded = [];

}

I use it as follows for example Game.php :


namespace App;

use App\Helpers\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class Game extends Model
{

//rest of class

}

In my test class I've set up a macro:


Model::macro('tableHeaders', function(){
    return array_keys($this->attributes);
});


It works perfectly. But now, my test suite is throwing new errors like this:

  1. Tests\Unit\GameTest::a_game_has_many_turns BadMethodCallException: Method App\Game::find does not exist.

or

  1. Tests\Unit\GameTest::a_question_set_can_be_filtered_by_a_user BadMethodCallException: Method App\Turn::where does not exist.

These all vanish as soon as I comment out the use Macroable from the parent model class.

Thanks for any advice you might have.

07 Nov
6 months ago

Roni left a reply on What About New Look @laracast.com

Looks awesome, performing a bit slow, but more than likely because we are all here at the same time looking at the new site :)

06 Nov
6 months ago

Roni left a reply on Anyone Ever See M:N Sync Do Some Ordering?

I updated it with results for clarity:


public function setPlayers($players)
    {
        $shuffled = $players->shuffle()->pluck('id')->all();

        dump($shuffled);

        $this->players()->sync($shuffled);
        dd($this->players->pluck('id')->values()->all());
    }



//RESULTS

PHPUnit 7.4.3 by Sebastian Bergmann and contributors.

array:5 [
  0 => 5
  1 => 3
  2 => 2
  3 => 1
  4 => 4
]
array:5 [
  0 => 1
  1 => 2
  2 => 3
  3 => 4
  4 => 5
]

Process finished with exit code 1

Roni started a new conversation Anyone Ever See M:N Sync Do Some Ordering?

It's been a long day and maybe my brain is used up but running this test always gives me back ordered id's even though I'm attempting to randomize the order they are stored in.


public function setPlayers($players)
    {
    //players are in order here
        $shuffled = $players->shuffle()->pluck('id')->all();
    //dd($shuffled); //everything is nicely shuffled here

        $this->players()->sync($shuffled);
        dd($this->players); //everything is back in order here!!!

    //Mind => blown

    }

Roni left a reply on Validating An Array

I find this super confusing and perhaps I'm not testing this correctly,

this validation rule works perfectly in all cases that I've tested (again I've left in commented lines:

I hate using this even though it passes every test because I'm not exactly sure what is going on.

I'm missing where each item is pulled to compare. But I can tell you without any hesitation that it IS doing it.


    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required',
//            'players' => 'required|array|min:1',
            'players' => [
                'required',
                'array',
                'min:1',
                Rule::exists('players', 'id')->where('account_id', auth()->accountId())
            ]
//                'int',
//                Rule::exists('players')->where(function ($query) {
//                    $query->where('account_id', auth()->accountId());
//                }),
//            ]
        ];
    }

If anyone could shed some light it would be appreciated.

Here is the updated test lines broken out for easy commenting


 /** @test */
    public function a_valid_game_will_be_stored() {
        $this->accountSignIn();

        $validPlayer1 = create(Player::class, ['account_id'=>auth()->accountId()]);
        $validPlayer2 = create(Player::class, ['account_id'=>auth()->accountId()]);
        $invalidPlayer = create(Player::class);
        $this->withExceptionHandling()
            ->submitValidGame([
                'players'=>[
                    $validPlayer1->id,
                    $validPlayer2->id,
//                    $invalidPlayer->id
                ]
            ])
//        dd(session()->get('errors')->getBag('default'));
        ->assertOk();

        $this->assertDatabaseHas('games', [
            'name' => 'Valid Game Name']);
    }


Roni started a new conversation Validating An Array

Hi Guys,

I'm trying to figure out validating a single field that contains an array

the data for the field will be generated by a vue components that will produce an array of integers


[1, 2, 3]

I want to validate that the input is in fact an array, (that part is fine) AND that each item in the array is an integer and in in a table with a specific account_id

Here is my code, I've tried a number of variations on based on the docs, but I can't seem to find the right one.

I'm calling this from a unit test so that the backend is all hooked up before I setup the visuals, I can't see that making a difference, but in case it does, now you know.


 public function rules()
    {
        return [
            'name' => 'required',  //Works
            'players' => 'required|array|min:1', //Works
            'players.*' => [
                'required',
                'int',
                Rule::exists('players')->where(function ($query) {
                    $query->where('account_id', auth()->accountId());
                }),
            ]
        ];
    }

I'm calling it from this unit test, I've left some of my hackery in trying to dig into this one.


    /** @test */
    public function a_valid_game_will_be_stored() {
        $this->accountSignIn();
        $player = create(Player::class, ['account_id'=>auth()->accountId()]);
        $this//->withExceptionHandling()
            ->submitValidGame(['players'=>[$player->id]] );

//        dd(session()->get('errors')->getBag('default'));
        //->assertOk();

        $this->assertDatabaseHas('games', [
            'name' => 'Valid Game Name']);
    }

here is the helper function submitValidGame


  protected function submitValidGame($overrides = [], $update = false)
    {
        return $this->post(route($update ? 'setup.update' : 'setup.store'),
            $this->validGameFields($overrides));
    }

    /**
     * @param $overrides
     * @return array
     */
    protected function validGameFields($overrides = []): array
    {
        try{
            return array_merge([
                'name' => 'Valid Game Name',
                'players'=> [1],
                'account_id' => auth()->accountId(),
            ], $overrides);
        }catch(\Exception $e){
            return [];
        }

    }

just in case, here is a snippet from the players migration

          
            $table->integer('account_id')->unsigned();
            $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');

and the relationship


    /**
     * Get the account that owns the Player.
     */
    public function account()
    {
        return $this->belongsTo(Account::class);
    }

the only thing I can't seem to make run is the players array specific item validation .

Thanks.

Roni left a reply on Add Custom Function To Auth Facade

@Edgar.Hauf , thanks!

I've noticed this won't work in a unit test


// WONT WORK in phpunit
auth()->user()->account

however this will work in a unit test and I think is very clear


SessionGuard::macro('account', function(){
    return auth()->user()->load('account')->account;
});


So you could use it like this in your unit tests


auth()->account()


Instead of the AppServiceProvider (I may add it there too for constancy) I jsut add it in my DomainTestCase file, setUp() method, just where I add macros that are specific to the project I'm working on, you could add it directly to TestCase and accomplish the same thing.