kevinbui

kevinbui

Member Since 4 Years Ago

Melbourne, Australia

Laravel Developer at Visual Domain

Experience Points 46,390
Experience Level 10

3,610 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 421
Lessons
Completed
Best Reply Awards 10
Best Reply
Awards
  • start-engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-session Created with Sketch.

    School In Session

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

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

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

  • subscriber-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist Created with Sketch.

    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 Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

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

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

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

16 Sep
3 days ago

kevinbui left a reply on LatestActivity Conditional

Is that the outcome that you want?

Also, do you name your model 'Tickets'? Ticket could be a better name.

kevinbui left a reply on Laravel Feature Test

Can you post the controller code as well?

There's nothing wrong with status code 302, its a redirect response. You may want to change the assertions to something like this:

$response->assertStatus(302)
                 ->assertViewHas('settings')
                 ->assertViewIs('setting::admin.index');

kevinbui left a reply on Laravel Feature Test

Does it say any errors when you uncomment $this->withoutExceptionHandling()?

kevinbui left a reply on LatestActivity Conditional

Inside the Ticket model, let's define a lastReply relationship:

class Ticket
{
    public function lastReply()
    {
        return $this->hasOne(Reply::class)->latest();
    }
}

Then get the tickets.

$tickets = Ticket::whereHas('lastReply', function ($query) {
    $query->where('user_id', '!=', auth()->user());
});
13 Sep
6 days ago

kevinbui left a reply on Complex Eloquent / SQL Request, Need Backup

What about this:

$authors = Author::whereHas('books.pages', function ($query) {
    $query->where('published', true);
});

kevinbui left a reply on Assign Value To Data Property From A Method In Vuejs

It's good that you are able to solve your own issue. I think that event handling thing got to be registered inside the CREATED or MOUNTED hooks.

export default {
    mounted() {
        grecaptcha.ready(() => {
                    grecaptcha.execute('6LeawrcUAAAAAIrA-LQ-kytjPFEBcedXDLcWHHHM', {action:      
                    'homepage'}).then((token) => {
                        this.RegForm.token = token;
                    });
                });
    }
}
07 Sep
1 week ago
28 Aug
3 weeks ago

kevinbui left a reply on Question Regarding Best Practice For Controller Methods

Checkout this talk . This is the best guide for making controllers! Maybe this is what you are looking for.

kevinbui left a reply on When Running Phpunit Test Following Error Occurs In Building Laravel App With TDD Episode 5

Can you show the code for a_user_can_create_a_project test case?

kevinbui left a reply on Phpunit: AssertArrayHasKey() - Undefined Index: Errors

Instead of creating your own function, what about using $response->assertSessionHasErrors();

26 Aug
3 weeks ago

kevinbui left a reply on Refactoring An Sql Sentence To Eloquent Style

As I understand, it would be more performant if we handle everything in one query.

25 Aug
3 weeks ago

kevinbui left a reply on Refactoring An Sql Sentence To Eloquent Style

Good point. I have updated my answer accordingly.

kevinbui left a reply on Refactoring An Sql Sentence To Eloquent Style

I assume that you have a Brand model, you might rewrite the query to something like:

$brands = Brand::select('brands.id', 'brands.name')
    ->join('products', 'products.brand_id', '=', 'brands.id')
    ->join('opportunities', 'opportunities.product_id', '=', 'products.id')
    ->where('opportunities.status', 1)
    ->groupBy('brands.name')
    ->get();

An alternative is to use whereHas and relationships. From your query I assume that a brand has many products and a product has many opportunities:

$brands = Brand::select('brands.id', 'brands.name')
    ->whereHas('products.opportunities', function ($query) {
        $query->where('status', 1);
    })->get();
17 Aug
1 month ago

kevinbui commented on Object-Oriented Forms: Part 1

Sorry, I didn't hear Jeffrey said that its not gonna work for more complex form.

kevinbui commented on Object-Oriented Forms: Part 1

Good lesson! But @keydown is not gonna work with some form elements, such as select. Is there any other event that can be used for all form elements?

03 Aug
1 month ago

kevinbui left a reply on Getting HasOne Relationship

Cool. Just a note on that, you may say:

optional($user->credit)->amount;

So even if a user has no credit, it still return null and dont raise any error.

kevinbui left a reply on Getting HasOne Relationship

Does that user has any credit?

kevinbui left a reply on Getting HasOne Relationship

Because you define a HasOne relationship so I think credit() could be a better function name.

public function credit()
{
    return $this->hasOne(Credit::class);
}

If you call the credit() function, you are gonna have a Illuminate\Database\Eloquent\Relations\HasOne object. If you want to access the credit model, pls say:

$user->credit->amount;
17 Jul
2 months ago

kevinbui left a reply on Groupby And Sum The Total_amount Of Same Suppliers

Interesting. Because we paginate the results, so $suppliers is an instance of Illuminate\Pagination\LengthAwarePaginator. Therefore, we are not able to use Higher Order Messages directly.

I have updated my answer slightly to consider that.

kevinbui left a reply on Groupby And Sum The Total_amount Of Same Suppliers

I have updated my answer accordingly.

15 Jul
2 months ago

kevinbui left a reply on FirstOrCreate On Multiple Related Records From XML Feed

So what data format did you have after using Rodenastyle/stream-parser?

kevinbui left a reply on Pass Array From Child To Parent

That looks a bit complicated. What about storing products in the WorkSheet component and then pass it down to the ProductCart components?

// WorkSheet.vue
<template>
<div>
    <ProductCart :products="products"/>
</div>
</template>

<script>
    import ProductCart from './ProductCart'
 
    export default {
        components: {
            ProductCart
        },
        data() {
            return {
                products: []
            }
        }
    }
</script>

So the WorkSheet component already got the products in the beginning.

kevinbui left a reply on Call Controller Function From Another Controller

I am not sure what your question is but it may not necessary to do so. Laravel supports heaps of redirecting mechanisms, including this redirecting to actions.

kevinbui left a reply on Call Model From Associate Table

This is a feature named Higher Order Message.

So the full form is gonna be:

$totalAmountDue = $child->user->payments->sum(function ($payment) use ($userId) {
    return $payment->usrAmountdue($child->user->id);
})

if ($totalAmountDue == 0) {
    ....
}

And of course, with higher order message, it become much simpler:

if ($child->user->payments->sum->usrAmountdue($userId) == 0) {
    ...
}

kevinbui left a reply on Call Model From Associate Table

If I understand your question correctly, what you want may be something like this:

if ($child->user->payments->sum->usrAmountdue($userId) == 0) {
    ...
}
22 Jun
2 months ago

kevinbui left a reply on Groupby And Sum The Total_amount Of Same Suppliers

@abdulbazith That's an interesting point. Payments for a supplier could have different due dates, so it's not possible to group by suppliers. I have updated my answer above, I basically put all due dates in one cell.

kevinbui left a reply on Groupby And Sum The Total_amount Of Same Suppliers

For better naming, I renamed the relationship from purchasetostore to payments.

public function payments()
{
    return $this->hasMany(PurchaseToStore::class, 'supplier_id');
}

We could make a query starting from the Supplier model, not the PurchaseToStore one.

$suppliers = Supplier::whereHas('payments', function ($query) use ($fromDate, $toDate) {
        $query->whereBetween('due_date', [$fromDate, $toDate]);
    })
    ->with(['payments' => function ()  use ($fromDate, $toDate) {
        $query->whereBetween('due_date', [$fromDate, $toDate]);
    }])
    ->paginate(50);

From the view (I assume that you use timestamp for the due_date field):

<thead>
    <tr>
        <th>S.No</th>
        <th>Supplier</th>
        <th>Due Dates</th>
        <th>Amount</th>
    </tr>
</thead>
<tbody>
@foreach($suppliers as $supplier)
    <tr>
        <td>{{$supplier->id}}</td>
        <td>{{$supplier->name}}</td>
        <td>{{
            $supplier->payments
                ->pluck('due_date')
                ->map
                ->format('d/m/Y')
                ->unique()
                ->implode(', ')
        }}</td>
        <td>{{$supplier->payments->sum('amount')}}</td>
    </tr>
@endforeach
</tbody>
<tfoot>
    <tr>
        <td colspan="4">Total: ${{$suppliers->getCollection()->map->payments->collapse()->sum('amount')}}</td>
    </tr>
</tfoot>
19 Jun
3 months ago

kevinbui left a reply on Help Me Refactor This Code Its A Bit Lengthy

Is it alright to make the order field a sequential value? If so, we can make that auto incremented in the migration file:

Schema::create('course_items', function (Blueprint $table) {
    // ...
    $table->signedInteger('order')->autoIncrement();
    // ...
});

Please let me know @successdav so I can update my answer accordingly.

17 Jun
3 months ago

kevinbui left a reply on Laracast Loads Very Fast

There is also a free course about optimisation:

https://serversforhackers.com/laravel-perf

12 Jun
3 months ago

kevinbui left a reply on PDF With QrCode

I did the same task before and those are the two packages that I used:

https://github.com/barryvdh/laravel-dompdf

https://github.com/endroid/qr-code

11 Jun
3 months ago

kevinbui left a reply on Grouping By Pivot Table Columns

You might try this:

$result = $thread->tags->groupBy(function ($tags) {
    return $tag->pivot->tag_type;
});

kevinbui left a reply on How To Add Extra Values In Every Result?

This would be a perfect case for accessor:

https://laravel.com/docs/5.8/eloquent-mutators#accessors-and-mutators

You could do something like:

use Illuminate\Support\Str;

public function getTempCodeAttribute($value)
{
    return "$value-" . Str::random(4);
}
04 Jun
3 months ago

kevinbui left a reply on Help Me Refactor This Code Its A Bit Lengthy

"Learn" is a weird model name. In this context, I think CourseItem could be better.

Lets define a relationship in the Course model:

class Course
{
    public function courseItems()
    {
        return $this->hasMany(CourseItem::class);
    }
}

According to a very popular speech: https://www.youtube.com/watch?v=MF0jFKvS4SI

I love to rewrite routing and controller this way. I also to prefer using relationship and request helper function to create a new course item.

Route::post('/courses/{courseId}/course-items', '[email protected]');
class CourseCourseItemsController
{
    public function store(Course $course)
    {
        $this->validate(request(), ['body' => 'required|spamfree']);

        return $course->courseItems()->create(request()->only('body'));
    }
}

Setting the order of a course item could be done in a model event: https://laravel.com/docs/5.8/eloquent#events

My understanding is that if you are not able to find a course item with an order of 1, you create a new item with an order of 2. So lets create a creating event like this.

namespace App\Events;

class CourseItemCreating
{
    public $courseItem;

    public function __construct(CourseItem $courseItem)
    {
        $this->courseItem = $courseItem;
    }
}

And the listener:

namespace App\Listener;

class IncrementOrderIfNeeded
{
    public function handle(CourseItemCreating $event)
    {
        if (CourseItem::where('order', 1)->exists()) {
            $event->courseItem->order = 2;
        } else {
            $event->courseItem->order = 1;
        }
    }
}

Then lets bind the event to the listener.

class CourseItem
{
    protected $dispatchesEvents = [
        'creating' => CourseItemCreating::class,
    ];
}
class EventServiceProvider
{
    protected $listen = [
        CourseItemCreating::class => [IncrementOrderIfNeeded::class]
    ];
}

kevinbui left a reply on Help With Test

Could I see the controller action too?

kevinbui left a reply on Laravel Scout Returns Empty

Please go to Algolia Client Dashboard and enter the same search term to see if it actually works.

kevinbui left a reply on How To Get Average Of Count Column

I think Martin's answer is close, but count is MySQL keyword, so its not accepted. Lets rename it to something else.

$dailyAverage = \DB::table('reviews')
            ->select(\DB::raw("to_char(date_trunc('day', created_at),'YYYY-MM-DD') as date, count(created_at) as     
            reviews_count"))
            ->whereIn('location_id', $locationIds)
            ->groupBy('date')
            ->avg('count');

Also, counting the created_at field is weird. I assume you want to count the number of reviews. So I rewrite it like this:

$dailyAverage = \DB::table('reviews')
            ->select(\DB::raw("to_char(date_trunc('day', created_at),'YYYY-MM-DD') as date, count(id) as     
            reviews_count"))
            ->whereIn('location_id', $locationIds)
            ->groupBy('date')
            ->avg('count');

kevinbui left a reply on Get Values From Relation In Collection After Get()

What do you mean "distinct rows from the relation"? Each ticket only has ONE type.

kevinbui left a reply on Retrieving Records From Child Table With Where Condition In Parent Table

I think this is a perfect use case for whereHas.

https://laravel.com/docs/5.8/eloquent-relationships#querying-relationship-existence.

So lets define a relationship in SpecificPurchaseBill model:

class SpecificPurchaseBill
{
    public function purchaseToStore()
    {
        return $this->belongsTo(PurchaseToStore::class);
    }
}

And then you might write a query like this (I have refactored a bit):

$all = SpecificPurchaseBill::where('hotel_id', Auth::user()->hotel_id)
    ->when(!empty(request('from')), function ($query) {
        return $query->whereBetween('d_date', [request('from_date'), request('to_date')]);
    })
    ->whereHas('purchaseToStore', function ($query) {
        $query->where('payment_status', 1);
    })
    ->orderBy('created_at', 'asc')
    ->get();
28 May
3 months ago

kevinbui left a reply on Is This Time Normal For My Tests?

Thats really fast for 227 test cases.

24 May
3 months ago

kevinbui left a reply on Check In Controller If Url Exists?

You can simply say:

if(! $coin) return abort(404);

kevinbui left a reply on Vue Form Not Hitting Controller Function

Can I see how you configure the route in web.php?

17 May
4 months ago

kevinbui left a reply on I'm Getting Errors When I Bind Vuex Getter Data

I don't think mapping a getter with param to a computed property is a good idea. Typically a computed property has no param:

https://vuex.vuejs.org/guide/getters.html#method-style-access

Lets use a method for the getter:

// I remove the mapState. getPageSettings is not a state to me.

methods: {
    getPage() {
         return this.$store.getters.getPageSettings(this.id)
    }
},
mounted () {
    // page is a piece of data for this component.
    this.page = this.getPage();
}

kevinbui left a reply on Passing Id To Getter Function

According to vuex documentation:

https://vuex.vuejs.org/guide/getters.html#method-style-access

We should use a method instead of a computed property for that getter:

// I assume the pageId is a prop.

methods: {
    getSettings() {
        return this.$store.getters.getPageSettings(this.pageId);
    }
}

I think we should not use computed properties with params.

16 May
4 months ago

kevinbui left a reply on Count Distinct Children Within Relationship

According to your thread title, there are two approaches to do this.

The first approach is to eager load distinctive events for each session.

$sessions = Session::withCount([
    'events' => function ($query) {
        $query->distinct();
    }
])
->whereBetween('end_time', ['2018-05-19 04:42:00', '2019-05-19 04:42:00')
->get()

The second approach is to join two tables together:

$sessions = Session::selectRaw('sessions.*, COUNT(DISTINCT events.id) AS events_count')
->join('events', 'sessions.id', '=', 'events.session_id')
->whereBetween('sessions.end_time', ['2018-05-19 04:42:00', '2019-05-19 04:42:00')
->get()

I have also noticed that the time range you put is nothing (from '2018-05-19 04:42:00' to '2018-05-19 04:42:00'). So please update this time range as well.

kevinbui left a reply on Where Are You All From?

Melbourne, Australia

15 May
4 months ago

kevinbui left a reply on Feature Tests Do Not Work (404)

Have you defined the route for that POST request?

kevinbui left a reply on How To Use Contains() On This Collection?

What is $onlineUsers a collection of? Is that a collection of eloquent models?

I reckon you might change it this way:

    @if ($onlineUsers->pluck('name')->contains($comment->user->name))
    @endif

kevinbui left a reply on Select All Data And Created Today

I assume that the table you are creating a query for named payments:

return Payment::where('payment_status', 'Cheq')
    ->whereBetween('created_at', [
        now()->startOfDay()->toDateTimeString(),
        now()->endOfDay()->toDateTimeString()
    ])->get();