schwartzmj

schwartzmj

Member Since 2 Years Ago

Experience Points
9,200
Total
Experience

800 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
82
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your 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-in-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 Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist 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.

Level 2
9,200 XP
Oct
04
2 weeks ago
Activity icon

Replied to Project Setup On DigitalOcean Npm Errors

What's the log say at /root/.npm/_logs/2020-10-04T23_53_13_622Z-debug.log?

Also, when you say you "installed npm" are you saying that you're running npm install or npm i within the project root before you run npm run prod?

Sep
30
3 weeks ago
Activity icon

Replied to Generating And Emailing Reports For All Users

@claudsonm

Quick question regarding Commands vs Jobs vs Queues, etc. Right now I have the following:

  1. A command called SendReport
  2. A Mail class called Report

I have not created a Job.

This is my SendReport Command's handle() method:

    public function handle()
    {
        $agency_users = User::where('role', 'agency')->get();
        foreach ($agency_users as $user) {
            Mail::to($user)->send(new AgencyAttentionReport($user));
        }
    }

And then in the Mail class's __construct method, I do a number of database queries for that user and then pass that data to the email view to be rendered and sent.

My Mail class implement's ShouldQueue so it should be automatically sent to the queue. Are all of the database queries still handled within the queue properly? In other words, since I'm bypassing creating a Job, is everything still functioning how I'd expect it to? Would a Job only be needed for more complex tasks?

Edit: Actually now that I think of it, I should probably create a job because there may be times where I do not want to send an email if some of the data comes back a certain way.

Sep
29
3 weeks ago
Activity icon

Started a new Conversation Generating And Emailing Reports For All Users

I'm looking to, every few days, generate a report for every user and then send it to them.

I was hoping to find some Google results or Laracasts videos to walk me through this, but was unable to find it. Could somebody point me in the right direction?

I understand that I should schedule a command to be ran every x days in Kernel.php, but I have two things I'm unsure of after that:

  1. Do I need to use Redis? Does Laravel perform job queues via the database if I don't set up Redis? My app is pretty simple, so I don't need anything extremely performant.
  2. What pieces of Laravel do I need for this? I'm unsure of what I should be searching for. For example, do I want to schedule a Job to be ran that runs a query to get each user, then Queues another job for each user to perform a calculation, which then generates and sends an email based on the results of the calculation? Do I fire off a job for each user or just the job that loops through each user? I'm assuming I'd queue every user report by themselves, so maybe I do something like:
$users = User::where(...query...);

foreach ($users as $user) {
	// ...queue a job for each user that performs a calculation and sends an email...
}
Sep
27
3 weeks ago
Activity icon

Replied to Localization & Jetstream

Hm... looks like I can just put it in the 'web' middleware and it works for Jetstream as well. Could have swore that I'd tried that already but it seems to work now.

Activity icon

Replied to Localization & Jetstream

@miguellima so unfortunately it doesn't look like this works. Auth::check() will always return false because middleware inside of the protected $middleware array hasn't run through authentication yet.

Sep
26
4 weeks ago
Activity icon

Replied to Localization & Jetstream

I’ll take a look at this. Thank you!

Sep
25
4 weeks ago
Activity icon

Replied to Localization & Jetstream

@miguellima Unfortunately you cannot access the current user there, because it has not gone through the authentication middleware yet. Unless I'm missing something.

Activity icon

Started a new Conversation Localization & Jetstream

I have Localization middleware that looks like this:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;

class GetSetLanguage
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        $user = $request->user();
        App::setLocale($user->language ?: "en");
        return $next($request);
    }
}

However, for any Jetstream routes, this will not work because I'm unable to tie into the Jetstream routes to add this middleware. Does anybody know how we should go about adding Localization to Jetstream?

Activity icon

Replied to HasOneThrough Where Two Models Are The Same Table

Even if somebody could point me in the right direction that would be very helpful :)

Sep
24
1 month ago
Activity icon

Started a new Conversation HasOneThrough Where Two Models Are The Same Table

Here's a brief summary of my models that I want to connect through a hasOneThrough relationship:

  1. User with $user->role === 'agency' and $user->id === 1
  2. User with $user->role === 'family' and $user->agency_id === 1
  3. Application with $application->family_id === 2 (or whatever the family id is)

A family user owns an application. An agency owns a family user. I'd like to be able to have an application object and call ->agency on it. This would be a hasOneThrough the family user that owns the application.

It sounds like this isn't possible because two of the models use the same table. Is that accurate?

Is it possible to construct a relationship like this via the query builder? Where i can get the agency by calling $application->agency instead of $application->agency() ?

A related issue

As a side note, I seem to be running into issues where, in an Application method, the family or agency methods are null. Does that have something to do with the model not being eager loaded?

For example, here's a method inside the Application model:

public function setApproved()
    {

        if (!$this->submitted_at) {
            $this->submitted_at = now();
        }
        $this->approved_at = now();
        $this->save();

        Mail::to($this->family)
            ->cc($this->agency)
            ->send(new ApplicationApproved(URL::to($this->path()))
            );

        return $this->approved_at;
    }

I've found that the $this->agency line in the Mail::to call doesn't always work. If I add $this->agency()->get(), then it seems to work. What's the technical reason for this just so I can understand what's going on better? Should I be making a database query for the family and agency within this method instead of relying on Eloquent to build these relationships?

Maybe more likely it's because my hacked together hasOneThrough for the agency is currently this:

   public function agency()
    {
        return $this->family->agency();
    }

While the family is what it should be:

    public function family()
    {
        return $this->belongsTo(User::class, 'family_id');
    }

If it helps, I first noticed this issue when writing tests. I didn't see it happen in real-world use yet.

Sep
23
1 month ago
Activity icon

Replied to Class SeeInOrder Not Found When Testing Component / Blade

Just wanted to add that I am having this same issue.

Sep
21
1 month ago
Activity icon

Started a new Conversation New To Laravel & PHP. Think I Found A Bug But Not Sure If I'm Just Doing It Wrong

I believe I may have found a bug involving Laravel & Telescope that has to do with event listeners. Usually when things go sideways like this, I'm just doing something wrong so I figured I'd bring it up and check with you guys.

I'm currently using Laravel v8.5.0 and Telescope v4.0.0, which at the time of writing should be the latest version of each.

First I'll link to the 7.0 version and 8.0 versions of the docs where the problem occurs:

These are the lines in particular for comparison:

7.0

public function subscribe($events)
    {
        $events->listen(
            'Illuminate\Auth\Events\Login',
            'App\Listeners\[email protected]'
        );

        $events->listen(
            'Illuminate\Auth\Events\Logout',
            'App\Listeners\[email protected]'
        );
    }

8.0

public function subscribe($events)
    {
        $events->listen(
            'Illuminate\Auth\Events\Login',
            [UserEventSubscriber::class, 'handleUserLogin']
        );

        $events->listen(
            'Illuminate\Auth\Events\Logout',
            [UserEventSubscriber::class, 'handleUserLogout']
        );
    }

Specifically this syntax: 'App\Listeners\[email protected]' vs [UserEventSubscriber::class, 'handleUserLogin']

Essentially, my app listens to the saved event of a particular model and then does something. I found that when this event gets fired, my app crashes with a 500 error and Telescope gives me this error: get_class() expects parameter 1 to be object, string given at vendor/laravel/telescope/src/Watchers/EventWatcher.php:91

If I change the syntax back to the 7.0 version, everything works fine.

The error would seem to make sense, because we are giving it a string and not an object (assuming ::class works how I think it does). Here's the line for reference in vendor/laravel/telescope/src/Watchers/EventWatcher.php:91:

                } elseif (is_array($listener)) {
                    return get_class($listener[0]).'@'.$listener[1];
                }

Would anybody else be able to give this a quick test and see if there's really a bug here or if I'm doing something wrong on my end?

Sep
20
1 month ago
Activity icon

Started a new Conversation Help Using OrderBy On Nested Relationship Query

I have a Livewire component that generates an HTML table where you can click a table header and sort the data. It also has a text input that you can type in to filter the results by name. I'm having issues getting the "sorting" part of it to work.

Relevant Users model with two Application model relations:

Get all applications for the user

    public function applications() // as family user, get their applications
    {
        return $this->hasMany(Application::class, 'family_id');
    }

Get the "current" (most recent) application for the user

    public function currentApplication()
    {
        return $this->hasOne(Application::class, 'family_id')->latest();
    }

Note that I'm trying to have a toggle that re-orders the Users list and not the list of applications. They're ordered by the currentApplication status (which is a number). In other words, the applications table has a status field.

The query

Here's what my query building looks like (see the lines just below the comment // Eager load current application & assign orderBy):

    public function render()
    {
        $this->authorize('viewAny', User::class);
        $user = auth()->user();

        if ($user->role === 'agency') { // Agency query
            $query = $families = $user->families();

        } elseif ($user->role === 'admin') { // Admin query
            $query = User::where('role', 'family');
        }
        // Eager load agency
        $query->with('agency');
            
        // Eager load current application & assign orderBy
        $query->with(['currentApplication' => function ($query) {
            $query->orderBy('status', $this->sortDesc ? 'desc' : 'asc');
        }]);

        // Apply any Name Filters
        if ($this->nameFilter) {
            $query->where('name', 'like', '%' . $this->escape_like($this->nameFilter) . '%');
        }

        $families = $query->paginate(10); // execute query (and paginate)
        return view('livewire.families-index', compact('families'));
    }

The results

Using Laravel Debug Bar, here's what my queries are looking like before toggling:

select * from `applications` where `applications`.`family_id` in (2, 4, 9, 10, 11, 12, 13, 14, 15, 16) and `applications`.`deleted_at` is null order by `created_at` desc, `status` asc

and after toggling:

select * from `applications` where `applications`.`family_id` in (2, 4, 9, 10, 11, 12, 13, 14, 15, 16) and `applications`.`deleted_at` is null order by `created_at` desc, `status` desc

This sorting doesn't seem to be working because I'm sorting the applications in the query, but I want to sort the families (users) based on the application.status. It doesn't look like I can ->paginate(10) to execute the query and then sortBy() the collection, because then my {{ $families->links() }} doesn't work in the Livewire component.

Sep
19
1 month ago
Activity icon

Replied to Help Building A Query Or Using Eloquent

@michaloravec The solution you gave is working, but I'm curious how it is working.

latest() sorts the collection, so I'm still pointing hasOne to a collection. Does hasOne just select the first item in the collection if it is a collection?

Is there a way I can explicitly point it at a single item instead of a collection?

Is this the line where it grabs the first item if you give it a collection?

If I wanted to grab the second or third one for some reason, I'm guessing I could apply an offset?

Activity icon

Replied to Help Building A Query Or Using Eloquent

I think this is pretty much what I'm looking for. I'm learning a lot today. Thank you again!

Thank you also @marianomoreyra for giving me some other methods to think about.

Activity icon

Replied to Help Building A Query Or Using Eloquent

How can I make it so it is just $family->application instead of $family->applications ?

I only want to get 1 application from the current year (they can only make one per year) and not the entire collection.

The issue I was having was that, in the view, I then have to go $family->getApplicationCurrentYear()->status which causes another database query

Activity icon

Started a new Conversation Help Building A Query Or Using Eloquent

I'm having some issues creating a query and structuring my data for a view.

I have a User model with role family that hasMany Applications

The view I'm displaying to the user is a table with the following table headings: Name, Email, and Year 2020 Application Status

Originally I was looping over every family and querying the database for every single row of the table in the view, which was causing hundreds of database queries. This is when I realized I should probably just query the database for all of the data I need in the controller and then send it to the view.

My goal is to query the database for the following:

  1. ALL Users with the role of "family"
  2. The current year's application for EACH family.
  3. If the family does NOT have a current year application, I want that field to still be there, but just null or some other falsy value.

One issue I'm having is that it looks like SQL "joins" merge all of the data together, so I have User data and Application within the same $family object. Is there a way to get the Application data to just be a key in the User data, like $family->application?

In my view I want to loop over each family and spit out a <tr> with the following data: $family->name, $family->email, $family->application->status.

$family->application can be null, so it'll be more like this for that <td>:

<td>
	@if($family->application)
		{{ $family->application->status }}
	@else
		Not Created
	@endif
</td>

Here's a few methods of retrieving data that I've tried which aren't quite what I'm going for:

                $data = DB::table('users')
                    ->where('role', 'family')
                    ->join('applications', function ($join) {
                        $join->on('users.id', '=', 'applications.family_id')
                            ->whereYear('applications.created_at', now()->year)
                    })
                    ->get();
                $family_users = DB::table('users')->where('role', 'family')->get();

                $applications_current_year = DB::Table('applications')
                    ->whereYear('created_at', now()->year)->get();

                return view('livewire.families-index')
                    ->with(compact('family_users', 'applications_current_year'));

                $this->families = User::where('role', 'family')
                    ->with([
                        'applications' => function ($query) {
                            $query->whereYear('created_at', now()->year);
                        }
                    ])
                    ->get();

Activity icon

Replied to Dynamic/conditional Relationships

Thank you for the thorough response, this helps a lot!

Activity icon

Replied to Dynamic/conditional Relationships

Hmm... this definitely makes me reframe how I thought relationships worked.

How come I'm even getting the error in the first place? In my mind the query works like this:

  1. Get all users where the "role" is "family"
  2. From those users, load their applications

In step two, I shouldn't have any "admin" users, so I shouldn't be hitting the error block. It sounds like the with() method doesn't function quite like how I thought it did when it looks at the applications() relationship.

My thinking of throwing an error was just a guard in the event that if I wrote my application incorrectly, then I would get a blatant error and could correct it... but it sounds like that isn't a good idea to throw an error in the relationship. I should just let it return an empty array for an admin?

Thank you for your help by the way!

Activity icon

Replied to Dynamic/conditional Relationships

Are you suggesting something like:

public function familyApplications() {
	$this->hasMany(Application::class, 'family_id');
}

public function agencyApplications() {
	$this->hasManyThrough(Application::class, User::class, 'agency_id', 'family_id');
}

Don't I still have to check for the proper role? Wouldn't this be accomplishing the same thing but just separating it out into two methods? I'm probably just misunderstanding. Could you elaborate?

Activity icon

Started a new Conversation Dynamic/conditional Relationships

My app is fairly simple, so I decided to hardcode 3 different roles onto users: 'family', 'agency', and 'admin'.

  • family users hasMany applications
  • agency users hasManyThrough applications, through a family user
  • admin do NOT have any applications

Here's how I've been doing the relationship (which is probably wrong?):

    public function applications()
    {
        if ($this->role === 'family') {
            return $this->hasMany(Application::class, 'family_id');

        }
        if ($this->role === 'agency') {
            return $this->hasManyThrough(Application::class, User::class, 'agency_id', 'family_id');

        }
        throw new \Exception('User is not an "agency" or a "family", so has no Applications.');
    }

I'm now encountering an issue where I want to query all families and then eager load their applications. Something like this:

                $this->families = User::where('role', 'family')
                    ->with('applications')
                    ->get();

This query results in the error User is not an "agency" or a "family", so has no Applications from my applications() relationship.

Obviously I'm probably doing something terribly wrong here and I've read through the docs, but I'm not sure how to proceed next. Does anybody have suggestions?

Sep
18
1 month ago
Activity icon

Replied to Run Validation On Model Already Stored In Database

Turns out my issue was that 'required|email' needed to be 'required|email:filter'

Apparently "[email protected]" is considered a valid email address if you don't tag on ':filter'.

Activity icon

Replied to Run Validation On Model Already Stored In Database

Thanks for the help. This seems a bit hacky or unintended. Is this a normal way of going about this? I'm surprised there's no "built in" way of doing it.

Sep
17
1 month ago
Activity icon

Started a new Conversation Run Validation On Model Already Stored In Database

I'm looking for a way to run validation rules on models already stored in my database. When searching for this, every resource that I find has to do with validating incoming form requests.

I've tried this inside of the model:

    protected $rules = [
        'name' => 'required',
        'address' => 'required',
        'city' => 'required',
        'zip' => 'required',
        'phone' => 'required',
        'email' => 'required|email',
        'authorize_release_information' => 'required'
    ];

    private $errors;

    public function validate()
    {
        $validator = Validator::make($this->attributes, $this->rules);
        if ($validator->fails()) {
            $this->errors = $validator->errors();
            return false;
        }
        return true;
    }

    public function errors()
    {
        return $this->errors->all();
    }

which seems to work, kind of. It seems to work for fields that are "required", and gives back the correct errors, but it considers an obviously incorrect email as valid (e.g. [email protected] is considered a valid email).

My use case is that I have a form that is automatically created and I want the user to update it, but I'd like to be able to tell them if there are currently errors or not from the automatically created form.

Sep
10
1 month ago
Sep
09
1 month ago
Activity icon

Started a new Conversation Implementing Some Simple Roles For Users

I went through Jeffrey's tutorial on creating Roles and Abilities models with a pivot table, but it seems like overkill for what I'm looking to accomplish.

Essentially, my app will have 2-3 types of users: Child, Parent, and Admin. These types of users (roles) will be able to interact with another model Application (a form) in different ways depending on their role. There are also links between Parents and Children via a foreign key.

The general public will not be able to register for accounts, or if they do, an Admin will have to assign them the proper role (which 100% of the time should just be "Parent'). This brings me to a side question: should I have an "Unapproved" or "Unassigned" role as a default role? This role wouldn't be able to do anything other than view a page that says "an Admin must approve your account".

Parents will be able to create a Child user account, which is linked to their account by a foreign key. Parents can also create Applications, but Child cannot. Child can only edit the Application that the Parent created for them.

Parents will have multiple Applications for multiple Children.

My primary question here is this: should I just hardcode my list of roles somewhere within my models (or somewhere else) instead of storing this information in the database? I imagine there being a role field on the User model that either has a key (1, 2, or 3), which then maps to a string in a roles array, or the User role might just be a string itself (admin, parent, or child).

If I'm understanding Policies correctly, it sounds like I'd do all of my logic for the Application model there. For example, the create policy on the ApplicationPolicy would deny you if your role was child. A Child would also only be able to view an Application if the application's child_id field was their own, etc.

Also, just to clear up a few things with my User model, it sounds like I'd have a nullable parent_id field on all of my User models, is that correct? I'd imagine that's how I'd tie together a child and parent (but a Parent or an Admin obviously wouldn't have a parent_id).

Sep
08
1 month ago
Activity icon

Replied to `App\` Not Working In Laravel 8

Ahh. So now it's App\Models\ because of the new Models folder.

I thought it had something to do with config/app.php and aliases, so I was going down that rabbit hole.

Thanks for leading me in the right direction.

Activity icon

Started a new Conversation `App\` Not Working In Laravel 8

I'm following Jeffrey's TDD course and he uses App\Project::all(); in the routes file. Within a brand new Laravel 8 installation this is giving me an Undefined namespace 'App' error.

I went back into a project I created 2 days ago (before Laravel 8), that I barely did any work in, and this piece of code works as expected.

I'm new to Laravel... am I missing something here?

Activity icon

Replied to Proper Way To Disable Personal Teams In Jetstream?

That makes sense. Maybe I can go the other way and when I check the user's teams, ignore any personal teams.

Activity icon

Started a new Conversation Proper Way To Disable Personal Teams In Jetstream?

I'd like to disable the creation of a "Personal Team" and force the user to either create a team or be invited to a team.

Here's what I've changed to make this work, so far:

Within \App\Actions\Fortify > CreateNewUser > create(), I've removed the creation of a personal team:

    public function create(array $input)
    {
        Validator::make($input, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', new Password, 'confirmed'],
        ])->validate();

        return DB::transaction(function () use ($input) {
            return User::create([
                'name' => $input['name'],
                'email' => $input['email'],
                'password' => Hash::make($input['password']),
            ]);
        });
//        return DB::transaction(function () use ($input) {
//            return tap(User::create([
//                'name' => $input['name'],
//                'email' => $input['email'],
//                'password' => Hash::make($input['password']),
//            ]),
//                function (User $user) {
//                $this->createTeam($user);
//            });
//        });
    }

However it looks like vendor/laravel/jetstream/src/HasTeams.php forces a currentTeam value of the user's Personal Team if they do not currently have a selected team.

    /**

     * Get the current team of the user's context.

     */

    public function currentTeam()

    {

        if (is_null($this->current_team_id)) {

            $this->forceFill([

                'current_team_id' => $this->personalTeam()->id,

            ])->save();

        }

 

        return $this->belongsTo(Jetstream::teamModel(), 'current_team_id');

    }

This seems like an issue since it is directly hardcoded within the Jetstream package. Should I search for uses of personalTeam and override various methods of the Jetstream package somehow?

Sep
06
1 month ago
Activity icon

Replied to Looking For Input On Structuring Models

I appreciate you taking the time to help me out and answer my questions. I'm going to read up on dataProviders and then get started. Thank you!

Activity icon

Started a new Conversation Looking For Input On Structuring Models

I'm building a pretty small, focused Laravel app. Here's the basic gist of it:

  1. User creates an account and fills out a form. Admin reviews the form and approves it.
  2. User has a second form to fill out now that the first is approved. Admin approves that form.
  3. Repeat once or twice more

There's other small details like notifications and such, but that's probably irrelevant to my question.

What's the best way to structure my models? Currently I'm doing something like this:

"FormGeneral" - First form that's filled out with general details. Has a column for each input field. Has an "approved_at" and "created_at" (submitted at) column.

Every other form is essentially the same as "FormGeneral", but with different columns for each input field that is unique to that form.

Additionally, I have an "Application" model that ties all these forms together into one entity with foreign keys.

As you can see, I'm repeating code between these "Form" models.

Testing

One of the things I'm most concerned about is writing tests. I can see myself adding or changing some form fields in the future, so I want my tests to make sure it sees the right form fields in the Blade templates, validates the right fields in the controller, etc. Is there some way to write a test that always knows what fields should be getting validated and should be getting rendered on the front end whenever I change the model? Otherwise I'd see myself having basically the same set of tests just copy & pasted from form to form. Or is that normal? Would I have to do something like structure the model fields like "FieldFirstName", "FieldAddress" and assume any column prefixed with "Field" is an input field to be tested?

Reusing code / extending models

How would I go about creating a class that all of these models extend, so I wouldn't be re-writing some of the basic functionality (like a method that checks if the form is completed and approved, for example). Is that what I'd use a Trait for?

General feedback

I'm also interested in just general feedback. Am I on the right track with how I'm structuring things? Any gotchas or anti-patterns I should watch out for?