Supercharge Your Laravel Development and Get AI to Understand Your Models
Hey there, Laravel enthusiasts! Today, I’m diving into a nifty trick that’ll make getting AI to understand your Laravel model structures a breeze. We’ll harness the power of bash scripting and AI to analyze our migrations quickly and efficiently. Let’s get started!
The Problem: Getting AI to Return Code For your Project Setup Easily
As our Laravel projects grow, so does the complexity of our database structures. Migrations pile up, relationships intertwine, and before you know it, you’re drowning in a sea of Schema::create
 and up
 functions. Wouldn’t it be great to get a bird’s-eye view of our models without manually sifting through dozens of files? What if you could get AI to understand your Laravel project without adding every file to the chat window?
The Solution: Bash + AI = Developer’s Best Friend
Here’s where our dynamic duo comes in a clever bash one-liner and your favorite AI chat tool (like ChatGPT or Claude). We’ll use bash to extract the relevant parts of our migrations and then feed that information to an AI for analysis and insights.
Step 1: The Magical Bash One-Liner
Here’s the one-liner code to copy and paste:
for file in *.php; do echo -e "\n\`\`\`\n${file%.*}:\n\`\`\`\n"; sed -n '/Schema::create/,/^ }/p' "$file"; echo -e "\n\`\`\`"; sed -n '/public function up/,/^ }/p' "$file" | sed '1d;$d'; echo -e "\`\`\`\n"; done
First, let’s break down our bash sorcery to understand what’s going on in an easier-to-read format:
for file in *.php; do
echo -e "\n\`\`\`\n${file%.*}:\n\`\`\`\n"
sed -n '/Schema::create/,/^ }/p' "$file"
echo -e "\n\`\`\`"
sed -n '/public function up/,/^ }/p' "$file" | sed '1d;$d'
echo -e "\`\`\`\n"
done
Just add | pbcopy to have it copied directly to your clipboard on Mac:
for file in *.php; do echo -e "\n\`\`\`\n${file%.*}:\n\`\`\`\n"; sed -n '/Schema::create/,/^ }/p' "$file"; echo -e "\n\`\`\`"; sed -n '/public function up/,/^ }/p' "$file" | sed '1d;$d'; echo -e "\`\`\`\n"; done | pbcopy
This command does the following:
- Loops through all PHP files in the current directory
- Extracts the
Schema::create
function contents - Extracts the
up
function contents (minus the function declaration) - Formats the output with the filename and proper Markdown code blocks
Step 2: Running the Command
- Open your terminal and navigate to your Laravel project’s migrations directory.
- Copy the bash one-liner above.
- Paste it into your terminal and hit Enter.
- Watch as it generates a nicely formatted output of your migrations!
Step 3: Feeding the Output to AI
Please copy the entire output from your terminal and paste it into your AI chat of choice with your preferred prompt. I usually start with this prompt:
"Analyze these Laravel migrations and understand the database and model structure, including relationships. For all conversations in this chat, refer to these migrations:"
{output here}
Generate a diagram
Here are some additional prompts you can optionally pair with the output to extract valuable insights and improvements:
- “Identify any potential relationships between these models based on the migrations.”
- “Suggest improvements or potential issues in this database design.”
- “Take this example of JSON output and generate the code to create the [model name] with its relations.”
The Benefits: Why This Approach Rocks
- Time-saver: No more manual searching through migration files or copying content manually or individually.
- Comprehensive view: Get a complete picture of your database structure in one go.
- AI-powered insights: Leverage AI to spot patterns, suggest optimizations, explain complex relationships, and generate code faster.
- Learning tool: Great for understanding legacy projects or onboarding new team members.
Wrapping Up
There you have it, folks! With this simple bash one-liner and the power of AI, you can transform how you analyze and understand your Laravel database structures and output code. Give it a try on your next project, and watch your productivity soar!
Remember, tools like these are meant to augment your skills, not replace them. Always review AI suggestions critically and trust your developer instincts.
How to Take Ownership of Files and Folders Using PowerShell
Ever had to take ownership of a bunch of files and folders? It’s a pain, right? Well, not anymore!
The Problem
Picture this: You’ve just gotten an external hard drive from a dead computer and need to access the files. But wait! You don’t have the correct permissions. I had to do this, and setting the file permissions through Explorer was failing randomly. It appears that the folders all had different permissions, and the propagation was failing.
The Solution
I’ve got a PowerShell script that’ll save you time. It does two things:
- Takes ownership of a folder and all its subdirectories and files (recursively) and sets the owner to the current logged-in user
- Adds the current user to the permissions with full control
The Script
First, here’s the script. Don’t worry, I’ll break it down for you:
# Ensure the script is running with administrator privileges
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
Write-Warning "You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator!"
Break
}
# Get the current user
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
# Function to take ownership and set permissions
function Set-OwnershipAndPermissions {
param (
[string]$path
)
try {
# Take ownership
$acl = Get-Acl $path
$owner = New-Object System.Security.Principal.NTAccount($currentUser)
$acl.SetOwner($owner)
Set-Acl -Path $path -AclObject $acl -ErrorAction Stop
# Set permissions
$acl = Get-Acl $path
if (Test-Path -Path $path -PathType Container) {
# It's a directory
$permission = $currentUser, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
} else {
# It's a file
$permission = $currentUser, "FullControl", "None", "None", "Allow"
}
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
Set-Acl -Path $path -AclObject $acl -ErrorAction Stop
Write-Host "Successfully processed: $path"
}
catch {
Write-Warning "Failed to process $path. Error: $_"
}
# Process subdirectories and files if it's a directory
if (Test-Path -Path $path -PathType Container) {
try {
Get-ChildItem $path -Force -ErrorAction Stop | ForEach-Object {
Set-OwnershipAndPermissions $_.FullName
}
}
catch {
Write-Warning "Failed to access contents of $path. Error: $_"
}
}
}
# Prompt for the folder path
$folderPath = Read-Host "Enter the full path of the folder"
# Check if the folder exists
if (Test-Path $folderPath) {
# Run the function
Set-OwnershipAndPermissions $folderPath
Write-Host "Process completed for $folderPath and all accessible contents."
} else {
Write-Host "The specified folder does not exist."
}
How to Use It
- Copy this script and save it as a
.ps1
file (liketake_ownership.ps1
). - Right-click on PowerShell and select “Run as administrator” (this is crucial!).
- Navigate to where you saved the script.
- Run it by typing
.\take_ownership.ps1
. - When prompted, enter the full path of the folder you want to process.
What’s Going On Here?
Let’s break this down a bit:
- Admin Check: The script starts by ensuring you run it as an admin. No admin rights? No dice.
- Current User: It grabs the current user’s name. This is who’s going to own everything.
- The Magic Function:
Set-OwnershipAndPermissions
is where the real magic happens. It:- Takes ownership of the item (file or folder)
- Sets the current user as the owner
- Gives the current user full control
- If it’s a folder, it does all this recursively for everything inside
- Error Handling: The script’s got your back with some neat error handling. It’ll let you know if it can’t process something and keep on truckin’.
- File vs. Folder: It’s smart enough to know the difference between files and folders and set the right permissions for each.
Why This is Awesome
- Time Saver: Imagine doing all this manually. Yikes!
- Consistency: It applies the same permissions everywhere, no mistakes.
- Flexibility: Works on any folder you point it to.
Wrapping Up
There you have it, folks! A powerful little script to take control of your files and folders. No more permission headaches, no more “access denied” nightmares — just pure, unadulterated file access bliss.
Got questions? Hit me up in the comments. And don’t forget to share this with your IT buddies – they’ll thank you later!
Happy scripting!
How to add case insensitive where in Laravel
Solving the Repetitive Query Dilemma: Harnessing the Power of Laravel Eloquent Macros
Have you ever found yourself writing the same complex database queries repeatedly? Yeah, me too. It’s frustrating, time-consuming, and, let’s face it, not the best use of our coding superpowers.
I needed to search some tables for case-insensitive values and discovered that Laravel doesn’t have a native function in eloquent, or it’s entirely possible that I missed it. Today, we will tackle this problem head-on by diving into the world of Laravel Eloquent macros. If you’ve never used them, this will be a game-changer for your productivity.
The Problem: Query Repetition Syndrome
Picture this: You’re working on a project where you frequently need to perform case-insensitive searches across multiple columns. Or maybe you’re constantly writing complex ordering logic to handle null values. Sound familiar?
If you’re nodding your head, you’re not alone. This is what I call “Query Repetition Syndrome,” and it’s a common ailment among Laravel developers.
The Solution: Eloquent Macros to the Rescue
Enter Eloquent macros – your new secret weapon against repetitive queries. These bad boys allow you to extend Eloquent’s query builder with custom methods. It’s like giving your Laravel app query superpowers!
Let’s break down how to implement this solution step-by-step.
Step 1: Create Your Macro Factory
First things first, we need a place to house our macros. Let’s create a new service provider:
php artisan make:provider MacroServiceProvider
Step 2: Set Up the MacroServiceProvider
Open up that freshly minted MacroServiceProvider.php
, and let’s give it some structure:
<?php
namespace App\Providers;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Arr;
class MacroServiceProvider extends ServiceProvider
{
public function boot(): void
{
$this->addWhereInLikeMacro();
$this->addWhereLikeMacro();
$this->addOrderByNullsLastMacro();
}
// We'll add our macro methods here
}
Step 3: Craft Your First Macro
Let’s tackle that case-insensitive search problem with a whereInLike
macro:
protected function addWhereInLikeMacro(): void
{
Builder::macro('whereInLike', function ($column, array $values, $caseSensitive = false) {
return $this->where(function ($query) use ($column, $values, $caseSensitive) {
$column = DB::raw($caseSensitive ? $query->getGrammar()->wrap($column) : 'LOWER(' . $query->getGrammar()->wrap($column) . ')');
foreach ($values as $value) {
$method = $query->getQuery()->wheres ? 'orWhere' : 'where';
$value = $caseSensitive ? "%$value%" : '%' . strtolower($value) . '%';
$query->$method($column, 'LIKE', DB::raw('?'));
$query->addBinding($value, 'where');
}
});
});
}
Step 4: Add More Macros to Your Arsenal
While we’re at it, let’s add a couple more handy macros:
protected function addWhereLikeMacro(): void
{
Builder::macro('whereLike', function ($columns, $value) {
return $this->where(function ($query) use ($columns, $value) {
foreach (Arr::wrap($columns) as $column) {
$query->orWhere(DB::raw('LOWER(' . $query->getGrammar()->wrap($column) . ')'), 'LIKE', '%' . strtolower($value) . '%');
}
});
});
}
protected function addOrderByNullsLastMacro(): void
{
Builder::macro('orderByNullsLast', function ($column, $direction = 'asc') {
$column = $this->getGrammar()->wrap($column);
$direction = strtolower($direction) === 'asc' ? 'asc' : 'desc';
return $this->orderByRaw("CASE WHEN {$column} IS NULL THEN 1 ELSE 0 END, {$column} {$direction}");
});
}
Step 5: Register Your Macro Provider
Don’t forget to tell Laravel about your new macros. Add this line to your config/app.php
:
'providers' => [
// Other providers...
App\Providers\MacroServiceProvider::class,
],
Step 6: Unleash Your New Query Superpowers
Now for the fun part – using your new macros:
// Case-insensitive search for multiple values
$users = User::whereInLike('name', ['John', 'Jane', 'Bob'])->get();
// Search across multiple columns
$users = User::whereLike(['name', 'email'], 'john')->get();
// Order results with nulls last
$users = User::orderByNullsLast('last_login')->get();
The Result: Clean, Efficient, and DRY Code
By implementing these Eloquent macros, we’ve solved our Query Repetition Syndrome. Instead of writing the same complex queries over and over, we have reusable, eloquent (pun intended) methods that make our code cleaner and more efficient.
But here’s the kicker – this is just the beginning. You can create macros for any repetitive query pattern in your projects. The possibilities are endless!
Wrapping Up
Eloquent macros are like a Swiss Army knife for your database queries. They’re powerful and flexible and can save you tons of time and headaches.
Remember, the goal here is to work smarter, not harder. By identifying repetitive patterns in your queries and turning them into macros, you’re setting yourself up for cleaner, more maintainable code in the long run.
Now, I’m curious – what repetitive query patterns have you encountered in your Laravel projects? Please drop a comment below to share your macros or share some macro solutions!
Happy coding, and may your queries be ever elegant!
How to Move Files by Partial File Name to New Directory on Mac using a shell script
Streamline Your Photo Editing Workflow: How to Use a Shell Script to Prioritize Selected Images
When it comes to photo editing, efficiency is key. Recently, I faced a challenge where a subject picked out 100 priority photos from a larger batch. Given the sheer number of images, manually sorting them wasn’t practical. All pictures from my SLR were named in the DCIM_# format, so I noted the last five numbers of the selected files. To streamline the process, I wrote a shell script that automatically moves the chosen files to a new folder, allowing me to focus on the priority images first. I’m sharing this script to help others enhance their photo editing workflow.
Step-by-Step Instructions on How to Run a Shell Script
Create the Shell Script:
- Open your favorite text editor (e.g., VSCode, Sublime Text, or even a basic text editor like Notepad).
- Write or paste your shell script. Here’s a simple example for moving selected files:
#!/bin/bash
# Directory containing the files
DIR="{Path}"
# Subfolder to move matching files to
TO_PROCESS_DIR="${DIR}/To Process"
# Ensure the "To Process" directory exists
mkdir -p "$TO_PROCESS_DIR"
# List of substrings to check
substrings=(
06340 06422 06500 06518 06521 06524 06539 06542 06545 06548 06553 06581
06584 06587 06608 06611 06617 06629 06649 06662 06980 06695 06733 06734
06737 06740 06743 06758 06761 06767 06773 06779 06787 06788 06791 06794
06797 06815 06818 06821 06845 06878 06890 06898 06899 06941 06947 06959
06962 06965 06970 06971 06977 06985 06986 07009 07040 07055 07062 07068
07074 07080 07083 07086 07089 07092 07097 07101 07104 07107 07113 07119
07128 07143 07146 07182 07185 07188 07191 07197 07200 07215 07218 07221
07230 07291 07302 07323 07329 07332 07338 07350 07356 07359 07476 07362
07365 07368 07389 07413 07435 07431 07461 07497 07500 07503 07506 07509
07512 07518 07524 07527 07530 07536 07542 07548 07557 07578 07584 07593
)
# Debugging: Check if the directory exists
if [ ! -d "$DIR" ]; then
echo "Directory $DIR does not exist."
exit 1
fi
# Debugging: Check if there are files in the directory
if [ -z "$(ls -A "$DIR")" ]; then
echo "No files found in the directory $DIR."
exit 1
fi
# Loop through all files in the directory
for file in "$DIR"/*; do
filename=$(basename "$file")
echo "Processing file: $filename"
moved=false
for substring in "${substrings[@]}"; do
if [[ "$filename" == *"$substring"* ]]; then
echo "Found substring '$substring' in file: $filename"
# Move the file to the "To Process" directory
mv "$file" "$TO_PROCESS_DIR"
moved=true
break
fi
done
if [ "$moved" = false ]; then
echo "No matching substring found in file: $filename"
fi
done
Save the Script:
- Save the file with a
.sh
extension, for example,move_photos.sh
.
Make the Script Executable:
- Open a terminal window.
- Navigate to the directory where your script is saved using the
cd
command. For example:cd /path/to/your/script
- Make your script executable by running:
chmod +x move_photos.sh
Run the Script:
- Still in the terminal, run your script by typing:
./move_photos.sh
Verify the Results:
- Check the destination directory to ensure that the files have been moved successfully.
Additional Tips:
- Editing the File List: Modify the
FILES
array in the script to include the specific last five digits of the filenames you want to move. - Updating Directories: Ensure that the
SOURCE_DIR
andDEST_DIR
variables are set to the correct paths on your system.
By following these steps, you can efficiently manage and prioritize your photo editing tasks, saving valuable time and effort. This shell script can be customized and expanded to suit various file management needs, making it a versatile tool in your workflow.
How to Automatically Login into Laravel App in Your Local Dev Environment
I often find myself spinning up Laravel projects for prototypes and idea testing and then letting them sit until I can pick them back up. Logging in whenever I start work gets annoying, and there’s no point in manually logging in to my local instance since my account is the admin. Fortunately, there are a few solutions to automate this process in Laravel. I’ll delve into the various methods to automatically log in to your Laravel app in your local development environment, enhancing your workflow and boosting productivity.
Utilizing session-based auto-login:
One approach to automating the login process for the Laravel application is session-based auto-login. This method involves setting up a mechanism that automatically logs in a predefined user whenever the application is accessed in the local development environment.
Each solution below assumes you’ve seeded or registered a local user account in your database.
1. Creating a custom route for auto-login:
You can create a custom route in your Laravel routes file (routes/web.php
) that triggers the auto-login functionality.
// routes/web.php
Route::get('/auto-login', function () {
$user = App\Models\User::find(1); // Fetch the user you want to auto-login
Auth::login($user);
return redirect('/dashboard'); // Redirect to a specific page after login
});
2. Implementing auto-login logic:
When you access the /auto-login
route in your local development environment, Laravel will automatically log in the specified user, redirecting them to the desired page (in this case, /dashboard
).
Leveraging custom middleware for auto-login:
Another method to automate your Laravel application’s login process is leveraging custom middleware designed for auto-login functionality. This approach provides more flexibility and control over the auto-login process, allowing you to define custom logic and conditions for authentication.
1. Creating a custom middleware for auto-login:
Generate a new middleware using the Artisan command make:middleware
.
php artisan make:middleware AutoLoginMiddleware
2. Registering the middleware in Laravel:
Register the custom middleware in the HTTP kernel (app/Http/Kernel.php
) to apply it to the desired routes or groups of routes.
// app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
// Other middleware...
\App\Http\Middleware\AutoLoginMiddleware::class,
],
];
Registering in the Boot method in AppServiceProvider:
This method allows you to log in automatically as soon as you load the application, and it is the method I use most often. I added a check to ensure that the environment is local.
if ($this->app->environment(‘local’)) {
$user = User::first();
if (isset($user)) {
$this->app[‘auth’]->setUser(User::first());
}
}
7-22-2024 – Update for the Boot method in AppService Provider
If you don’t have the user table seeded with a user, the above code will cause an error when running the seeders. I tweaked the code to check for the table’s existence to avoid the error when running seeders.
if ($this->app->environment('local') && \Illuminate\Support\Facades\Schema::hasTable('users')) {
$user = User::first();
if (isset($user)) {
$this->app['auth']->setUser(User::first());
}
}
Bonus: Generating a seeder for the Users table
Sometimes, you might want to seed your database with an admin user for testing purposes. Here’s how you can do it:
A. Creating a UserSeeder class:
Generate a new seeder class using the Artisan command make:seeder
.
php artisan make:seeder UserSeeder
B. Seeding the database with an admin user:
Within the generated UserSeeder
class, define the logic to create an admin user.
// database/seeders/UserSeeder.php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use App\Models\User;
class UserSeeder extends Seeder
{
public function run()
{
User::create([
'name' => 'Admin',
'email' => 'admin@example.com',
'password' => Hash::make('password'), // Change this to something more secure
// Additional user data...
]);
}
}
Finally, run the seeder using the Artisan command db:seed
.
php artisan db:seed --class=UserSeeder
Following these steps, you can seamlessly integrate auto-login functionality into your Laravel application’s local development environment, reducing the time and effort spent on repetitive login tasks. Additionally, seeding your database with an admin user ensures that you have a user account available for testing and development purposes.
How to enable MacFuse/PCloud Drive on Mac Sonoma 14.2.1
I recently upgraded to Mac Sonoma 14.2.1 and MacFuse stopped loading which affected my ability to load PCloud and NTFS drives. I spent a few days trying to troubleshoot everything and in the end it turned out I had to disable Mac System Integrity Protection to get everything to load. I’m sharing in case it helps anyone else.
To disable SIP on your Mac Sonoma for extensions like MacFuse and pCloud Drive:
- Shut down your Mac: Turn off your Mac completely by pressing and holding the power button until the screen goes black.
- Restart in Recovery Mode: Enabling Recovery Mode depends on your Mac. You can try the steps below or follow Apple’s guide here.
Power on your Mac and immediately press and hold Command (⌘) + R to enter Recovery Mode.
Power on your Mac and hold the power button down until Other Options displays. - Open Terminal: In Recovery Mode, select “Utilities” in the macOS Utilities window and select “Terminal.”
- Disable SIP: Type
csrutil disable
in Terminal and press Enter. This disables System Integrity Protection (SIP). - Restart Mac: Click the Apple menu and select “Restart” to reboot your Mac with SIP disabled.
- Re-enable SIP (if needed): Follow the same steps but use
csrutil enable
in Terminal to re-enable SIP.
Note: Disabling SIP poses security risks. Re-enable it once you’ve installed the necessary extensions. Only disable SIP when necessary and understand the potential risks involved.
How to Delete a Row in Excel Using the Elgato Stream Deck
Recently I was working on a massive Excel Spreadsheet and needed to manually review each entry and clean up rows that were no longer needed. The Elgato Stream Deck came in handy for a quick shortcut so I thought I’d share it in case anyone else can use it.
I took this opportunity to practice creating the first of what I hope are many training videos. This took me around 30 minutes to do from start to finish as I had to learn the video editing software including how to record, how to split and edit, and how to add text overlays. Hopefully the next videos will be faster but it was a fun exercise and I hope someone else finds it useful.
Installing font awesome pro with bun
After recently switching to bun.sh, I was trying to install Font Awesome Pro. It uses a private registry but their docs have not been updated to support non-npm package managers and bun does not yet support .npmrc files.
You can configure a private registry using an organization scope. First, you must get your auth token from your paid Font Awesome account by going to your account page, scrolling down to the Tokens section, and copying the token.
Copy and paste this string, and replace YOUR_TOKEN_HERE with the token you copied above:
[install.scopes]
"@fortawesome" = { token="YOUR_TOKEN_HERE" , url =
"https://npm.fontawesome.com/"}
Open the terminal and enter these commands:
touch $HOME/.bunfig.toml
nano $HOME/.bunfig.toml
Paste in the config above with your token and then hit CTRL+X to quit, and Y to save when prompted. Now you should be able to run
bun add @fortawesome/fontawesome-pro
A sonnet about Batman in the style of William Shakespeare
Oh Batman, knight of darkness, hero bold
Fierce in battle, strong in heart and mind
Defender of the weak and young, behold
Thy righteous justice, keen and unconfined
With cape and cowl, thou roam’st the gloomy night
In search of evil, lurking in the shade
With batarangs and gadgets, swift and right
Thou fight’st with valor, never unafraid
Thou art the Dark Knight, feared by thy foes
But loved by Gotham, city of thy birth
Thy loyal allies, Robin and Batgirl knows
Thy strength of spirit, unmatched on this earth
Oh Batman, thy courage doth inspire
Thy legend shall never fade, nor expire.
AI Experiments Featuring Monkeys
I was experimenting with AI writing and images and was experimenting. My initial testing was for serious subject matters, and it proved to be surprisingly well-written.
I decided to experiment to see how absurd things could get and was not disappointed. Here’s the first result.
A sonnet about monkeys in the style of William Shakespeare
Oh primate of the jungle wild, with fur so soft and warm,
Your funny face is full of cheer, your spirit full of charm.
Your leaps and bounds are so delight, your antics such a sight,
Your antics bring joy and laughter, day and night.
Your antics full of curious play, never a dull moment today,
Your cries bring life to the trees, your presence is here to stay.
Your chatter fills the air with sound, as you swing from tree to tree,
Your kind is full of joy, of this much I guarantee.
Your life is full of family, and you are never lonely,
Your love and care for one another, is so pure and honestly.
Your life is filled with plenty of adventure, curiosity and more,
Your life is full of joy, and near the jungle floor.
Oh primate of the jungle wild, I sit and watch you play,
Your furry face and kind spirit, I shall never forget today.
Your life is full of joy and cheer, your presence warm and bright,
Your life is full of love and fun, and I am glad to be in your sight.