tylernathanreed

tylernathanreed

Member Since 3 Years Ago

Dallas

Experience Points 52,690
Experience Level 11

2,310 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 642
Lessons
Completed
Best Reply Awards 13
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.

17 May
2 months ago

tylernathanreed left a reply on Renaming A Column In SQLite On A Table Referenced By A Foreign Key Fails

This is still a problem for me. Does anyone have any ideas?

21 Apr
2 months ago

tylernathanreed left a reply on Renaming A Column In SQLite On A Table Referenced By A Foreign Key Fails

@nomguy

I tried that first, and it didn't work. I figured I'd try Laravel's equivalent, just in case that did something else, but that didn't work either.

:/

19 Apr
2 months ago

tylernathanreed left a reply on Renaming A Column In SQLite On A Table Referenced By A Foreign Key Fails

I also just tried changing my migration code to this:

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        DB::transaction(function() {

            Schema::disableForeignKeyConstraints();

            Schema::table('users', function (Blueprint $table) {
                $table->renameColumn('name', 'display_name');
            });

            Schema::enableForeignKeyConstraints();

        });
    }

And I'm getting the same exception. How am I supposed to rename columns in SQLite?

tylernathanreed left a reply on Renaming A Column In SQLite On A Table Referenced By A Foreign Key Fails

@nomguy That would have the same issue. Seeing as I can't even get this migration to go through, due to this exception, I'm not even at a point where I can run the down code.

tylernathanreed started a new conversation Renaming A Column In SQLite On A Table Referenced By A Foreign Key Fails

I'm trying to add a username column to my users table (which currently just has the standard columns provided in a new Laravel project on it). To avoid confusion with the name column, I wanted to first rename the name column to display_name.

I attempted to do so using the following migration:

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->renameColumn('name', 'display_name');
        });
    }

Which results in the following exception:

SQLSTATE[23000]: Integrity constraint violation: 19 FOREIGN KEY constraint failed (SQL: DROP TABLE users)

I was immediately concerned that I coded something wrong, but upon further inspection, this appears to be the standard for SQLite. Here's the SQL the migration is trying to run:

CREATE TEMPORARY TABLE __temp__users AS
    SELECT
        id,
        name,
        email,
        email_verified_at,
        remember_token,
        created_at
        updated_at,
        password
    FROM users

DROP TABLE users

CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    email VARCHAR(255) NOT NULL COLLATE BINARY,
    email_verified_at DATETIME DEFAULT NULL,
    remember_token VARCHAR(255) DEFAULT NULL COLLATE BINARY,
    created_at DATETIME DEFAULT NULL,
    updated_at DATETIME DEFAULT NULL,
    password VARCHAR(60) DEFAULT NULL COLLATE BINARY,
    display_name VARCHAR(255) NOT NULL
)

INSERT INTO users (
    id,
    display_name,
    email,
    email_verified_at,
    remember_token,
    created_at,
    updated_at,
    password
)
    SELECT
        id,
        name,
        email,
        email_verified_at,
        remember_token,
        created_at,
        updated_at,
        password
    FROM __temp__users

DROP TABLE __temp__users

This is basically creating a temp table with the new column, dropping the original table, then recreating the table, and filling in the data. While this would technically get the job done, this also ignores all issues regarding foreign keys.

I understand that there's probably ways around this (such as just creating a new column and dropping the original, or disabling foreign key constraints for migration), but I haven't seen any mentioning of this requirement on the Laravel documentation, and I'm currently under the impression that what I'm doing is supposed to work without any gimmicks.

Am I doing something incorrectly here, or is this a bug?

28 Dec
6 months ago

tylernathanreed left a reply on Unable To View Action Events On User Detail Page

Bump.

Is there any additional information I can provide here to help you guys answer my question?

21 Dec
6 months ago

tylernathanreed started a new conversation Unable To View Action Events On User Detail Page

As the title suggests, I am unable to view the Action Events log. It just shows up with a blank listing and the "No action matched the given criteria." message.

I only have the one user in my system, as I'm still tinkering around with things, but I've definitely performed several actions (as my actions log in my database shows many records).

After looking at the API call to display the listing of actions, I am indeed getting zero results back:

~/nova-api/action-events?search=&filters=&orderBy=&orderByDirection=desc&perPage=25&trashed=&page=1&viaResource=users&viaResourceId=1&viaRelationship=actions&relationshipType=hasMany

{
"label": "Actions",
"resources": [],
"prev_page_url": null,
"next_page_url": null,
"softDeletes": false
}

However, I went into the ResourceIndexController in the Nova source code, and dumped out the query to see what it was trying to do, and I think I've discovered the problem:

"select * from "action_events" where "action_events"."actionable_id" = 1 and "action_events"."actionable_id" is not null and "action_events"."actionable_type" = 'App\Models\User' order by "action_events"."id" desc"

I'll be honest, I'm not quite sure I understand the difference the "actionable", "target", and "model" morph on the "action_events" table, but all three morphs seem to be storing the same information (being the model that was acted upon).

However, I would think that this query would be looking at either "user_id", since that contains the foreign key to my user. If the "actionable_id" is supposed to be my user id, then Nova isn't storing action events correct.

Just to be certain, I updated my Nova instance to 1.2.1, and I'm still seeing this issue.

Any thoughts here?

17 Sep
10 months ago

tylernathanreed left a reply on How To Convert Laravel Query To Db::raw

@pordonez

No, because the bindings escapes SQL to prevent it from changing the code. You're also trying to concatenate an array to a string.

You're better off doing this:

DB::table('leads')->whereIn('lead_agent', $array)->orderBy('created_at', 'desc');

tylernathanreed left a reply on Counting Days Between Two Dates Per Data-row

@wilco You can do this in eloquent, but not easily.

Also, I might have misplaced some parenthesis. I typed it up on my phone.

16 Sep
10 months ago

tylernathanreed started a new conversation Add Prompt For "New Discussion" Button

When the current page has a form that has been filled out, pressing the "New Discussion" button should prompt with a "Are you sure you want to do this?" style message.

If someone hits the "New Discussion" button instead on the submit button (presumably on accident), they are redirected away from the current form, and all of their work will be lost.

This has tripped me up on mobile a couple of times. I know it's user-error, but having a handy feature to prevent that from happening would be great.

tylernathanreed left a reply on Wanna Get All Articles A User Has Favourited

Your point of failure is the $favorite->article call is returning null.

Could you post how you've set up the article relation on your Favorite model?

15 Sep
10 months ago

tylernathanreed started a new conversation Automatic Form Model Binding

I've created a component for a generic <form>:

<template>
    <form>
        <slot></slot>
    </form>
</template>

And I'm using it as a simple form wrapper:

<v-form method="POST" action="{{ route('register') }}">
    @csrf

    <div class="form-group row">
        <label for="name">Name</label>
        <input id="name" type="text" name="name" value="{{ old('name') }}" required autofocus>
    </div>

    <!---->
</v-form>

I would like my Vue component to read the slot contents and automatically bind to form inputs (such as the name field) without having to hard code data: function() { return {'name': null}; } or tack on the v-model="name" attribute on the input element.

Since I know that my component is isolated to a form, it wouldn't think it difficult to programmatically find all of the input HTML elements and automatically bind to them.

Is this possible with Vue? Normally I'd whip out jQuery and have this problem solved quickly, but I'm trying to learn the Vue equivalents to things.

14 Sep
10 months ago

tylernathanreed left a reply on Counting Days Between Two Dates Per Data-row

I'll be honest here: this isn't easy. However, it's not impossible.

Your main problem here is allowing for overlap. Here's what a traditional overlap means:

Definition A: If another Services record exists for the same user_id, where its date_from or date_to values range between the date_from or date_to of the Service record in question, then the Service record in question is overlapped by the other Service.

Since overlap is allowed, if we were to just aggregate the date difference between date_from and date_to, our count would potentially be too high, as we would have counted certain date ranges more than once, explicitly where overlap has occurred.

But what if we could count overlap, but ensure that we only count it once?

If we redefine what "overlap" means in a special way, we can solve our problem:

Definition B: If another Services record exists for the same user_id, where its date_from or date_to values range between the date_from or date_to of the Service record in question, and the id of the other Service is higher than the Service in question, then the Service record in question is overlapped by the other Service.

To get a total count, per service, we can execute the following database query:

select
    services.id,
    services.date_from,
    services.date_to,
    case
        when datediff(day, coalesce(max(start_overlaps.date_from), services.date_from), coalesce(min(end_overlaps.date_to), services.date_to)) + 1 > 0
            then datediff(day, coalesce(max(start_overlaps.date_from), services.date_from), coalesce(min(end_overlaps.date_to), services.date_to)) + 1
        else 0
    end as [non_overlapping_days]
from services
    left join services as start_overlaps
        on start_overlaps.user_id = services.user_id
            and start_overlaps.id > services.id
            and start_overlaps.date_from between services.date_from and services.date_to
    left join services as end_overlaps
        on end_overlaps.user_id = services.user_id
            and end_overlaps.id > services.id
            and end_overlaps.date_from between services.date_from and services.date_to
group by
    services.id,
    services.date_from,
    services.date_to

And if we want this per user, per service type, we can use the following database query:

select
    days_per_service.user_id,
    days_per_service.service_type,
    sum(days_per_service.non_overlapping_days) as days
from services
    inner join (
        select
            services.id,
            services.user_id,
            services.service_type,
            services.date_from,
            services.date_to,
            case
                when datediff(day, coalesce(max(start_overlaps.date_from), services.date_from), coalesce(min(end_overlaps.date_to), services.date_to)) + 1 > 0
                    then datediff(day, coalesce(max(start_overlaps.date_from), services.date_from), coalesce(min(end_overlaps.date_to), services.date_to)) + 1
                else 0
            end as non_overlapping_days
        from services
            left join services as start_overlaps
                on start_overlaps.user_id = services.user_id
                    and start_overlaps.id > services.id
                    and start_overlaps.date_from between services.date_from and services.date_to
            left join services as end_overlaps
                on end_overlaps.user_id = services.user_id
                    and end_overlaps.id > services.id
                    and end_overlaps.date_from between services.date_from and services.date_to
        group by
            services.id,
            services.user_id,
            services.service_type,
            services.date_from,
            services.date_to
    ) as days_per_service
        on days_per_service.user_id = users.id
group by
    days_per_service.user_id,
    days_per_service.service_type

See if that works for you.

tylernathanreed left a reply on How To Convert Laravel Query To Db::raw

The second parameter to DB::select(...) is your bindings. This means that you can do this:

DB::select('select * from leads where lead_agent in ?', $array)

tylernathanreed left a reply on Coalesce Not Working In Laravel

The Illuminate\Database\Query\Expression class is used whenever you have a DB::raw(...) statement. Given that you're trying to convert this to an integer in a jQuery datatable, odds are that your passing something to your front-end incorrectly.

tylernathanreed left a reply on Admin Panel

@shez1983 Have you considered using Laravel Nova?

https://nova.laravel.com/

24 Aug
10 months ago

tylernathanreed left a reply on List All Database Column Names And Types Laravel 5.6

Use this:

DB::getDoctrineSchemaManager()->listTableColumns($table)
30 Jan
1 year ago

tylernathanreed left a reply on Require('js') Returns Empty Object

Yes, of course.

I'm on the latest LTS for Node.js and npm. I've also been running npm run watch without issues (other than the fs issue I've described here).

29 Jan
1 year ago

tylernathanreed started a new conversation Require('js') Returns Empty Object

I'm working with some of the node.js functionalities within Laravel, namely using laravel-mix, and I'm encountering a problem with my source code.

For whatever reason, require('fs') is returning an empty object, essentially preventing me from using the module.

I've already tried adding fs: 'empty' to my webpack configuration:

let mix = require('laravel-mix');

mix.webpackConfig({
    node: {
        fs: 'empty'
    }
});

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css')
   .sourceMaps();

Which didn't solve the problem.

I'm using Windows 10 right now, and I tried running it on Windows 7 this morning. Neither of which worked.

Is there something I'm doing wrong?

21 Jun
2 years ago

tylernathanreed left a reply on Polymorphism: Why Should I Violate Database Design?

@jimmck If the morphable_type column is stored on a separate table, then how would the application know what table morphable_id references? I've never heard of this being done. Are you perhaps thinking of Class Table Inheritance or Single Table Inheritance?

If there's an alternative implementation that Polymorphism that solves some or all of my issues with it, then I'd love to learn more.

20 Jun
2 years ago

tylernathanreed left a reply on Polymorphism: Why Should I Violate Database Design?

@martinbean My views towards Laravel's implementation of polymorphic relations is that it actually does it very well. The real issue I have is with polymorphism in itself.

I eventually just used to argument of "Eloquent is my database abstraction layer, so as long as I use that to enforce my relationships, I'll be fine", as my original issue with Polymorphism was that I couldn't enforce/create Foreign Keys. However, I also eventually learned that every now and then you do have to go down to the database layer, and run raw queries on it (This is outside of the code, and typically run for one-off cleanups or reporting). I could argue that this is in fact bad practice when using Polymorphism, because you create the possibility of leaving orphaned records. However, it can be difficult to get away from it when the pointy-haired boss is telling you to do it.

@jimmck morphable_type and morphable_id are stored in the same table as per Laravel's implementation of polymorphism. Without the morphable_type column, you don't know what table you're joining to. If you're always going to join to the same table, then you don't need polymorphism. In this case, a simple Foreign Key would suffice.

That is effectively the alternative to Polymorphism: Create a bunch of Foreign Keys, and loose the "morphable" concept all together. However, once you start making heavy use of this practice, you'll discover that you have tons of pivot tables and tons of joins. Joins are a necessary means, but they should be minimized for the sake of performance. In the world of Acadamia, performance doesn't matter all that much, so this approach is typically taken.

This is what put this thought in my mind in the first place. Polymorphism is essentially loosing the ability to use Foreign Keys for the added benefit of simplifying your relationships and minimizing the number of tables and joins you have. The major drawback to Polymorphism is the loss of Foreign Keys. If you're not careful, you can leave a bunch of orphaned records.

16 Jun
2 years ago

tylernathanreed left a reply on Polymorphism: Why Should I Violate Database Design?

@martinbean This topic has always sat in the back of my mind. No worries.

At my workplace, we're using Laravel, and we're making use of polymorphism quite a bit. We've really only had one big issue with them: There are no foreign keys. Sometimes we forget about certain tables when deleting records (We have a 289 tables right now, so it can be difficult to keep stuff straight). This leaves records that shouldn't exist in our database, and it can break certain code pieces on the polymorphic table that assumed its polymorphic relation existed.

The only other potential issue we've had is our vendor integration. Sometimes we have to give third-party businesses read access to our application. Showing them the <morphable>_type data gives some clue into how our code-base is structured. This issue isn't big enough to deter me from polymorphism, but it is big enough to point out.

After a year of trying out both design patterns, I can definitely say that polymorphism is very useful, but comes with some problems that I mentioned in the OP. I know that in the workforce, the mentality is basically "Screw the problems, we'll find ways around it", which is fine, but that gut feeling of "I told you so" comes back to bite me every time we have issues related to polymorphism.

17 Nov
2 years ago

tylernathanreed left a reply on Eloquent - Where Date Range Overlaps, Either Before And/or After, Another Date Range

As far as logic goes, you want this:

  • The Start Date of the Event happened before To
    • i.e. To needs to be in the future from the perspective of the Start Date.
  • AND The End Date of the Event happened after From.
    • i.e. From needs to be in the past from the perspective of the End Date.

In this example, your query would be:

    $user = User::where('id', Auth::user()->id)
      ->with([ 'events' => function($query) use ($from, $to) {
        $query->where('start', '<=', $to)->where('end', '>=', $from)
      }])
      ->first();

To clean things up a bit, I like to add "Time" Macros to all of my Queries:

AppServiceProvider::boot():

    \Illuminate\Database\Query\Builder::macro('past', function($column, $when = 'now', $strict = true) {

        $when = Carbon::parse($when);
        $operator = $strict ? '<' : '<=';

        return $this->where($column, $operator, $when);
    }

    \Illuminate\Database\Query\Builder::macro('future', function($column, $when = 'now', $strict = true) {

        $when = Carbon::parse($when);
        $operator = $strict ? '>' : '>=';

        return $this->where($column, $operator, $when);
    }

This would allow you to make queries like this:

    $user = User::where('id', Auth::user()->id)
      ->with([ 'events' => function($query) use ($from, $to) {
        $query->past('start', $to)->future('end', $from)
      }])
      ->first();

To take things a step further, I'd add this as a scope to your Event Model:

    public function scopeOverlapping($query, $from, $to)
    {
        return $query->past('start', $to)->future('end', $from);
    }

Which further clarifies your original query to:

    $user = User::where('id', Auth::user()->id)
      ->with([ 'events' => function($query) use ($from, $to) {
        $query->overlapping($from, $to);
      }])
      ->first();

Now then, a few optimizations:

Judging the context of this query, you're wanting to load the overlapping events onto the Authenticated User. Seeing as you already have the Model, it might make more sense to do this:

    $events = Auth::user()->events()->overlapping($from, $to)->get();

If you really need the Authenticated User to be passed along with an $events variable, you can always do this:

    $user = Auth::user()->setRelation('events', $events);

This could be inlined as:

    $user = Auth::user()->setRelation('events', 
        Auth::user()->events()->overlapping($from, $to)->get()
    );

This effectively does exactly the same thing, but I consider it to be more readable than a ->with construct using an array and a closure.

Hopefully somewhere along writing all of this, I managed to answer your question.

tylernathanreed left a reply on Cannot Use App\Product As Product Because The Name Is Already In Use

Oddly, this can happen when your Namespaces and Includes don't match. My guess is that you incorrectly defined the Namespace for your Product Model.

Are you certain that your model is under the App Namespace? I know that some developers put it under the App\Models Namespace.

tylernathanreed left a reply on Laravel 5.1 Multiple Login

@fikri1510 That's because you're still using the 5.1 RedirectIfAuthenticated Middleware. You need to be using the one from 5.2.

03 Nov
2 years ago

tylernathanreed left a reply on Many To Many - Pivot Tables

So, is this your table structure?

pilots
    id

subunits
    id

tasks
    id
    subunit_id

pilots_subunits
    pilot_id
    subunit_id

pilot_tasks
    pilot_id
    task_id

Clearly, if you want the Tasks of a Pilot, you do this:

$pivot->tasks

And if you want the Tasks of a Subunit, you do this:

$subunit->tasks

But if you want the Tasks of all Subunits of a Pilot, then you are correct in that it is complex. However, I'd do this:

$pivot->subunits()->with('tasks')->get()->pluck('tasks')->collapse();

That is to say, "Get all of the Subunits of this Pilot, with it's Tasks, then grab only those Tasks, then collapse the collection (Because you have a collection of collections until you do that)."

Also, because this was grabbed through a BelongsToMany relation, each Task with have a Pivot Entry containing the associated Subunit ID.

tylernathanreed left a reply on Eloquent Relationship Returns Null When Using Query Scope

@ianmcqueen Yes. Any method call that the relationship doesn't have calls the underlying query instead.

As for storing Events, I've done this in the past, but with a single model, called EventLog, which looked like this:

event_log
 - id (big increments)
 - event (string 255) [This contains the Class Path of the Event, i.e. "App\Events\MarkedLessonComplete"]
 - data (text / json) [Contains JSON of all parameters passed to Event Constructor]
 - fired_at (datetime)

I'm not sure if anything about what I did then applies to your current application through.

However, when I'm naming my classes, the last "studly word" ("Event" in this case) typically denotes what type of object it is.

Here's a few examples:

  • MySqlConnection
  • SqliteConnection
  • UserPresenter
  • RolePresenter
  • ArticlesTableSeeder
  • CommentsTableSeeder
  • PagesController
  • AuthController
  • CountryPolicy
  • StatePolicy

All of these are children of their suffix (Connection, Presenter, Seeder, Controller, Policy). So if I see "MarkedLessonCompleteEvent", my brain immediately tells me "This object must extend App\Events\Event or some similar class." When this ends up not being the case, it leads to confusion.

This is why I called my model "EventLog" instead of "Event". It also allows the natural flow of things to look like this:

public function(EventLog $entry)
{
    /* ... */
}

You're free to call things whatever you like, but you might save yourself some hassle in the future when you make the same assumption I did, and turn out to be wrong.

tylernathanreed left a reply on How Transform This Collection

@divanoli Makes sense. If that's the case, then you want your collection to look like this:

{
    "Windows & Doors" => {},
    "Kitchen Items" => {},
    "Wrought Iron" => {
        5 => "Staircase",
    },
    "Stainless Steel" => {
        6 => "Staircase"
    }
}

To get a Select Box like this:

  • Window & Doors
  • Kitchen Items
  • Wrought Iron
    • Staircase
  • Stainless Steel
    • Staircase

If your input is an array, then you want this:

$collection = collect($array);

$select = $collection->keyBy('title')->map(function($item) { return collect($item['child'])->lists('title', 'id'); })

However, if these "items" are Models, and "child" is a nested relation, then you don't need the collects:

$select = $collection->keyBy('title')->map(function($item) { return $item->child->lists('title', 'id'); })

Seeing as child is an array, I would personally use children instead. Either way, you'll end up with this:

Form::select('item', $select->toArray())

To get the following HTML:

<select name="name">
    <optgroup label="Windows &amp; Doors"></optgroup>
    <optgroup label="Kitchen Items"></optgroup>
    <optgroup label="Wrought Iron">
        <option value="5">Staircase</option>
    </optgroup>
    <optgroup label="Stainless Steel">
        <option value="6">Staircase</option>
    </optgroup>
</select>

Personally, I'd exclude groups that have no selectable options. If you're using the second option, you can do this:

$select = $collection->keyBy('title')->map(function($item) { return $item->child->lists('title', 'id'); })->reject(function($item) { return $item->isEmpty(); })

To instead get this:

<select name="name">
    <optgroup label="Wrought Iron">
        <option value="5">Staircase</option>
    </optgroup>
    <optgroup label="Stainless Steel">
        <option value="6">Staircase</option>
    </optgroup>
</select>

Hope that helps.

25 Oct
2 years ago

tylernathanreed left a reply on How Transform This Collection

You're mixing ordered arrays with associative arrays, and then ignoring the case of something in your nested relations, which uses a third style of formatting.

Are you absolutely certain that it needs to be in this format? Why not this:

[
    1 => {
        "title": "Windows & Doors",
        "child": []
    },
    2 => {
        "title": "Kitchen Items",
        "child": []
    },
    3 => {
        "title": "Wrought Iron",
        "child": [
            5 => {
                "title": "Staircase",
            }
        ]
    }
    4 => {
        "title": "Stainless Steel",
        "child": [
            6 => {
                "title": "Staircase",
            }
        ]
    }
]

tylernathanreed left a reply on Eloquent Relationship Returns Null When Using Query Scope

I'd double check your join. Make sure that there's a subscription tied to that User.

Side Note:

Are MarkedLessonCompleteEvent and MarkedSegmentCompleteEvent Models? Their class names indicate that they're Events. The names themselves shouldn't be causing any issues, it's just a bit misleading to me.

tylernathanreed left a reply on Make Blade @push And @stack Dynamic

No, but you can do this:

@push('layout.0')
    ...
@endpush

@push('layout.1')
    ...
@endpush

@push('layout.2')
    ...
@endpush

@for($i = 0; $i <= 2; $i++)
    @stack("layout.{$i}")
@endfor

If your naming convention isn't that clean, you could do this instead:

@push('foo')
    ...
@endpush

@push('bar')
    ...
@endpush

@push('baz')
    ...
@endpush

@foreach(['foo', 'bar', 'baz'] as $stack)
    @stack($stack)
@endforeach

tylernathanreed left a reply on Multi-Auth In Laravel 5.1

I ended up creating my own package for this. I've been using it for awhile now, and I've been making tweaks as I go.

This is more or less 5.2 Multi-Auth ported into 5.1. There's also some 5.3 features that I'm integrating as well.

Check it out here: https://github.com/tylernathanreed/laravel-auth

31 Jul
2 years ago

tylernathanreed left a reply on Eloquent Multiple Joins

Fun fact: You can Eager Load using closures:

Area::select([
    'id',
    'province_id',
    'column AS alias',
    /* ... */
])->with([
    'province' => function($query) {
        return $query->select([
            'id',
            'country_id',
            'column AS alias',
            /* ... */
        ]);
    },
    'province.country' => function($query) {
        return $query->select([
            'id',
            'column AS alias',
            /* ... */
        ]);
    }
])->get();

Result:

Illuminate\Support\Collection: {
    #items: [
        0 => App\Models\Area {
            'id' => 1,
            'province_id' => 1
            'alias' => /* ... */
            'province' => App\Models\Province {
                'id' => 1
                'country_id' => 1,
                'alias' => /* ... */
                'country' => App\Models\Country {
                    'id' => 1
                    'alias' => /* ... */
                }
            }
        }
        /* ... */
    ]
}

Get be sure to pull in any Foreign Keys / Primary Keys that are used in the joins for the Eager Loading, or else the relationship will return an empty set.

30 Jul
2 years ago

tylernathanreed started a new conversation Never Execute A Duplicate Query Again

I bet you have Barryvdh's Debug Bar or some equivalent enabled, and you're seeing tons of duplicate queries, and you simply don't have the time to track them all down.

Boy do I have the solution for you!

Have you considered caching every single query per request? Check this out:

Every SELECT query in Laravel, whether it's using Eloquent, or the DB Facade, all runs through a single function. We're going to override that function:

~/app/Support/Database/Builder.php

<?php

namespace App\Support\Database;

use Cache;
use Illuminate\Database\Query\Builder as QueryBuilder;

class Builder extends QueryBuilder
{
    /**
     * Run the query as a "select" statement against the connection.
     *
     * @return array
     */
    protected function runSelect()
    {
        return Cache::store('request')->remember($this->getCacheKey(), 1, function() {
            return parent::runSelect();
        });
    }

    /**
     * Returns a Unique String that can identify this Query.
     *
     * @return string
     */
    protected function getCacheKey()
    {
        return json_encode([
            $this->toSql() => $this->getBindings()
        ]);
    }
}

So, we're caching every query by it's SQL and it's Bindings. Neat, right? But what's this all about?

Cache::store('request')->...

That's right, we need to set up a custom Cache Driver. We're doing this so that we don't mess with any existing Cache logic you might already be using. Here's how I've defined this:

~/config/cache.php

'stores' => [
    'request' => [
        'driver' => 'array'
    ]
]

In case you're wondering, the array driver is an in-memory Cache store that just stores everything inside an array. This is typically wiped at the end of each request, as once the application gives a response, this is naturally freed from memory. This is actually exactly what we want, as we only care about queries being run within the same request.

Just in case you decide to set things up differently, you can flush the Cache at the end of every request by adding this:

~/public/index.php

try
{
    // Flush the Request Cache
    $app->make('cache')->store('request')->flush();
}
catch(ReflectionException $ex)
{
    // Do nothing
}

After the $kernel->terminate($request, $response) statement.

Now, don't go trying this yet, as it's not going to work. Remember how we "created" a custom Query Builder? Well, we have to tell our Models how to use it. This can be done with the following trait:

~/app/Support/Database/CacheQueryBuilder.php

<?php

namespace App\Support\Database;

trait CacheQueryBuilder
{
    /**
     * Get a new query builder instance for the connection.
     *
     * @return \Illuminate\Database\Query\Builder
     */
    protected function newBaseQueryBuilder()
    {
        $conn = $this->getConnection();

        $grammar = $conn->getQueryGrammar();

        return new Builder($conn, $grammar, $conn->getPostProcessor());
    }
}

You'll want to slap this on any Model that you want to use this new feature:

~/.../SomeModel.php

<?php

namespace App;

use App\Support\Database\CacheQueryBuilder;
use Illuminate\Database\Eloquent\Model;

class SomeModel extends BaseModel
{
    /**
     * For Caching all Queries.
     */
    use CacheQueryBuilder;
}

And viola! Give it a try! See what happens!

29 Jul
2 years ago

tylernathanreed left a reply on Laravel 5.1 Multiple Login

Here's a package that I'm working on: https://github.com/tylernathanreed/laravel-auth

It's literally just Multi-Auth from Laravel 5.2 refactored and dropped into 5.1.

I've actually gotten this to work in an existing 5.1 project, so I know that it does the basics. If you have any troubles setting it up, let me know. This package is still early in its development, so any feedback would be appreciated.

21 Jul
2 years ago

tylernathanreed left a reply on How Does Composer Know The Patch Version Of My Package?

@willvincent All of the Tags that I've created for my repository are automatically made as Releases on GitHub. Is this because my tags are using the vX.Y.Z notation?

20 Jul
2 years ago

tylernathanreed left a reply on How Does Composer Know The Patch Version Of My Package?

@willvincent Then can I have a Tag that doesn't refer to a Release?

tylernathanreed left a reply on How Does Composer Know The Patch Version Of My Package?

@ricardovigatti Even Composer itself recommends against specifying a Version Number, as humans are prone to errors.

@willvincent How unusual. That's quite an odd feature to duplicate.

19 Jul
2 years ago

tylernathanreed left a reply on How Does Composer Know The Patch Version Of My Package?

@ricardovigatti Tags might just be the solution I was looking for. I thought that this was done with Tags, but I couldn't find it on the Laravel Framework Repository.

Turns out that was because GitHub doesn't show that option on mobile, and that was where I started doing my research.

Let me assert an answer, and tell me if I'm understanding this correct:

To inform Composer of a Patch Version, I apply a Tag to specific Commit that should represent that Patch. The name of the Tag should match the Composer Versioning pattern, meaning a Tag of v5.1.22 maps to laravel/framework: "5.1.22". And using laravel/framework: 5.1.* grabs the latest Patch based on the version.

That said, what's the difference between a Release and a Tag in terms of GitHub?

tylernathanreed left a reply on How Does Composer Know The Patch Version Of My Package?

@wolle404 Then why doesn't Laravel have 5.1.1, 5.1.2, 5.1.3, ... , and 5.1.40 branches? It only has a 5.1 branch.

@ricardovigatti Yes, I know this, and that's not what I asked.

I'm wanting to *create a package. I know how to use packages, and I know how versions are specified on the composer.json file for pulling in other packages.

If I want to have patch versions on my custom built composer package, how do I specify these without a branch for each patch (Minor versions will have their own branches)?

18 Jul
2 years ago

tylernathanreed left a reply on How Does Composer Know The Patch Version Of My Package?

But where? And what goes in it?

I know that there's a composer.lock file, but that serves a different purpose.

17 Jul
3 years ago

tylernathanreed left a reply on One-To-Many Polymorphic Relationship

This relationship seems n:n to me.

n:n always looks like 1:n from the perspective of the calling Model. If this happens on both sides, you have an n:n relationship.

Consider these functions within these Models:

Customer.php

public function tags()
{
    // Plural, ?:n
}

Tag.php

public function customers()
{
    // Plural ?:n
}

This is n:n. A 1:n would look like this:

Customer.php

public function tag()
{
    // Singular ?:1
}

Tag.php

public function customers()
{
    // Plural ?:n
}

OR

Customer.php

public function tags()
{
    // Plural, ?:n
}

Tag.php

public function customer()
{
    // Singular ?:1
}

The first example shows a 1:n between Customers and Tags (or n:1 between Tags and Customers).

The second example shows an n:1 between Customers and Tags (or 1:n between Tags and Customers).

The same logic applies to Timelogs. You have an n:n relationship there too.

tylernathanreed started a new conversation How Does Composer Know The Patch Version Of My Package?

I've always been confused by this.

Let's take the laravel/framework repository as an example. Obviously, each branch denotes the Major and Minor versions (X.Y i.e. 5.1, 5.2, etc.), but how are the Patch versions determined (X.Y.Z i.e. 5.1.40, 5.2.14, etc.)?

I'm curious about this because I'm already working on creating my own package, and I'd like to specify my Patch versions.

12 Jul
3 years ago

tylernathanreed left a reply on Multi-Auth In Laravel 5.1

@jlrdw Sorry, but no. This just looks like Laravel Socialite.

08 Jul
3 years ago

tylernathanreed left a reply on Sharing One Database For 2 Laravel Apps?

Personally, I'd move all of the common logic between the two applications into a separate Git Repository, so that I'm not duplicating my Models and what-not on both applications. I do this with private software all the time:

composer.json

repositories: [
    {
        type: "vcs",
        url: "../packages/<package-name>"
    }
]

Where the projects are stored like this:

~/www*

project-1
project-2
packages
    <package-name>

Then, make sure that all of the Models that come from the package share a database connection. Maybe something like this:

~/config/database.php (In both Projects)

'core' => [
    'driver'    => 'mysql',
    'host'      => env('DB_CORE_HOST', 'localhost'),
    'database'  => env('DB_CORE_DATABASE', 'forge'),
    'username'  => env('DB_CORE_USERNAME', 'forge'),
    'password'  => env('DB_CORE_PASSWORD', ''),
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => 'core_',
    'strict'    => false,
],

This means that all core Models are on the same database, and because these Models are from a single package, you've basically got yourself a pseudo-project that two projects share.

The remaining implementation is a pure design choice. Here's the choice, and the results:

Is there a Model is one of the projects, that needs to have relationships with a Core Model?

Yes

Then either make that Model a Core Model, and the other project doesn't have to use it.

OR

Give the project a connection on the same database as core, but with a different prefix. (This was hinted at by @phpMick )

No

Then the project can have it's own database connection, and do whatever it pleases.

OR

Still give the project a connection on the same database as core, but with a different prefix.

Notice that in both cases, there's an option to give the project a connection on the same database as core, but with a different prefix. By choosing this route, you then do not care if project-specific Models share information with Core Models, because in either case, they can communicate.

I've done this before, where I have an internal application for a customer service rep to use, and an external application for a customer to use (Like checking your Bank Statements online, versus a Bank Employee managing your account internally). We ended up with schema looking similar to this:

internal_user
    id
    username
    password
    ...

internal_customer
    id
    name
    ssn
    credit_card
    ...

external_user
    id
    customer_id (FK on internal_customer)
    username
    password
    ...

This happened to be a great use-case for Multi-Auth, but it allowed us to separate internal and external logic. They may have shared the same database, but from Laravel's point of view, they were completely different.

tylernathanreed left a reply on Business Logic In Frontend Using Backend As API

One of the projects I've worked on used two applications, one for server-side logic, and the other for the public-facing portion of the site.

Both projects used Laravel, one being a typical MVC app, but the other was 90% Views, 10% Controllers. The Controllers just made API Calls and handed the information over to the Views.

Also, we did the API calls using Curl Requests, rather than Ajax requests, but the same logic applies.

tylernathanreed left a reply on Multi-Auth In Laravel 5.1

I need to authenticate over two different tables, one for Users (standard auth), and one for Api Users (token auth).

I'm not using Capcha or "I am not a robot". Those are really for validation, not authentication.

tylernathanreed left a reply on Multi-Auth In Laravel 5.1

@christopher The package you recommended as been abandoned.

Pretty much every package I've found online uses a custom solution, where as I'd like to have 5.2 Multi-Auth in 5.1.

I suppose I could just pull the source code from 5.2, and make a package out of that...

04 Jul
3 years ago

tylernathanreed left a reply on Featured Series On Home Page

@SaeedPrez Yes, but my complaint is that I can't reach the latest lesson(s) from the Home Page. Sure, I'm venturing out to other pages now, but it would be nice to see what the latest video was from the home page.

This is why I recommended having some be the latest. Obviously it's a good idea to have some core series on the Home Page, but having an easy way to access some of the latest content would be nice too.

03 Jul
3 years ago

tylernathanreed left a reply on Redirecting To An Intended Route

@Snapey I'm curious about that as well. The default just goes to /. I'd much rather have that set an intended flag on the Redirector, and allow the route function to pick up on that.

I think that the method should be changed to this:

public function intended($default = null, $status = 302, $headers = [], $secure = null)
{
    $path = $this->session->pull('url.intended', $default);

    return $path === null ? $this : $this->to($path, $status, $headers, $secure);
}

@d3xt3r I don't hate it, I just prefer cleaner alternatives. Why intentionally jumble stuff up if you can keep it clean?