grozavule

Member Since 1 Year Ago

Experience Points
9,210
Total
Experience

790 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
67
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.

  • Community Pillar

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

Level 2
9,210 XP
May
05
3 days ago
Activity icon

Replied to Create A Query Joining Three Eloquent Models

If I understand what you're saying, I could use any of the three models to formulate my query. I just can't use all three together.

May
04
4 days ago
Activity icon

Started a new Conversation Create A Query Joining Three Eloquent Models

I have the following SQL query that I need to replicate using Eloquent:

SELECT SUM(COL.ORDER_QTY) as UNITS_SOLD, SR.NAME
FROM CUSTOMER_ORDER CO JOIN SALES_REP SR ON CO.SALESREP_ID = SR.ID
JOIN CUST_ORDER_LINE COL ON CO.ID = COL.CUST_ORDER_ID
WHERE COL.PART_ID LIKE 'MODEL%' AND CO.ORDER_DATE > '2018-05-01'
GROUP BY SR.NAME
ORDER BY UNITS_SOLD DESC

I created three Eloquent models for CUSTOMER_ORDER, SALES_REP, and CUST_ORDER_LINE.

CUSTOMER_ORDER

<?php

namespace App\Visual;

use Illuminate\Database\Eloquent\Model;

class CustomerOrder extends Model
{
    protected $connection = 'vmfg';
    protected $table = 'CUSTOMER_ORDER';
    protected $primaryKey = 'ID';
    protected $keyType = 'string';

    public function lineItems()
    {
        return $this->hasMany('App\Visual\CustomerOrderLine', 'CUST_ORDER_ID', 'ID');
    }

    public function salesRep()
    {
        return $this->belongsTo('App\Visual\SalesRep', 'SALESREP_ID');
    }
}

SALES_REP

<?php

namespace App\Visual;

use Illuminate\Database\Eloquent\Model;

class SalesRep extends Model
{
    protected $connection = 'vmfg';
    protected $table = 'SALES_REP';
    protected $primaryKey = 'ID';

    public function orders()
    {
        return $this->hasMany('App\Visual\CustomerOrder', 'SALESREP_ID');
    }
}

CUST_ORDER_LINE

<?php

namespace App\Visual;

use Illuminate\Database\Eloquent\Model;

class CustomerOrderLine extends Model
{
    protected $connection = 'vmfg';
    protected $table = 'CUST_ORDER_LINE';
    protected $primaryKey = 'ROWID';

    public function order()
    {
        return $this->belongsTo('App\Visual\CustomerOrder', 'CUST_ORDER_ID');
    }
}

How can I leverage these models to create the equivalent of the SQL query above?

Apr
30
1 week ago
Activity icon

Awarded Best Reply on Model Saves Two Records To Database

It ended up that that quotes in the JSON object were causing my issues. I needed to addslashes after the object was encoded and stripslashes before the object was decoded.

Activity icon

Replied to Model Saves Two Records To Database

It ended up that that quotes in the JSON object were causing my issues. I needed to addslashes after the object was encoded and stripslashes before the object was decoded.

Activity icon

Replied to Model Saves Two Records To Database

Here is what the generateJsonError() method outputs:

"{"WORKORDER_NUMBER":"97321-471","TRAVELER_NUMBER":"123","PART_NUMBER":"134592","MESSAGE":"THE PART NUMBER, 134592, WAS IDENTIFIED AS A MIRRORED PART, BUT ITS SIBLING COULD NOT BE FOUND"} ◀"
Activity icon

Replied to Model Saves Two Records To Database

The problem is being caused by this line:

$error->error = $this->generateJsonError();

Only one record is saved per ValidationError when I changed it to the following:

$error->error = 'TEST';

Why would passing a JSON string to this property cause two records to be created?

Activity icon

Replied to Model Saves Two Records To Database

The save() method that I posted isn't overwriting the model's save()method. The save() method that I posted is in a completely separate class. Inside the separate class, the ValidationError object is instantiated and saved. Does that help?

Activity icon

Started a new Conversation Model Saves Two Records To Database

One of my models, ValidationError, saves two records for each object that I create, and I can't figure out why.

This is all that I have in the ValidationError class:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ValidationError extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

Here is the function that calls ValidationError::save():

public function save()
{
    $error = new ValidationError;
    $error->application = getCurrentApplication();
    $error->error = $this->generateJsonError();
    $error->generated_by = auth()->id();
    $error->assigned_group = $this->assignedGroupId;
    $error->save();
}

During my troubleshooting, I verified that the save() function above is only being called once for each error. From what I can tell, something is happening on the model level to insert two records per ValidationError object.

Apr
24
2 weeks ago
Activity icon

Started a new Conversation Sending Two Different Notifications For A Single Event

In my application, a user can request a quote. When the quote request form is submitted, I would like to notify the user via email that the request was received. I would also like to notify the site owner that a request has been received. Somewhere in all of this, the request details need to be saved to a database.

I assume that I can create two different notifications: one for the end user and another for the site owner. One of the notifications will send an email and save to the database. The other will just send an email. Is this the best way to do this?

Apr
14
3 weeks ago
Activity icon

Started a new Conversation File Upload Produces Duplicate Database Entry

I have a form that uploads multiple files. Somehow the controller that handles the request creates two database records for each uploaded file. The HTTP request shows the proper number of files sent. The $request object passed into the controller method shows each file twice.

Here is the controller method:

public function store(Request $request)
    {
        $validInput = Validator::make($request->all(), [
            'first_name' => ['required', 'string', 'max:35'],
            'last_name' => ['required', 'string', 'max:50'],
            'email_address' => ['required', 'email:rfc,dns', 'max:125'],
            'phone_number' => ['required', 'string', 'max:15', 'regex:/^[+]*[0-9]*\s*[(]*[0-9]{3}[)]*[\s\.\-]*[0-9]{3}[\.\-]*[0-9]{4}$/'],
            'quantity' => ['required', 'integer','min:1'],
            'material' => ['required', 'string', 'max:50'],
            'due_date' => ['required', 'after:today'],
            'company_name' => ['required', 'string', 'max:75'],
            'files' => ['required']
        ]);

        if($validInput->fails())
        {
            return Response::json($validInput->errors(), 400);
        }

        $quote = new Quote;
        $quote->first_name = $request->input('first_name');
        $quote->last_name = $request->input('last_name');
        $quote->email_address = $request->input('email_address');
        $quote->phone_number = $request->input('phone_number');
        $quote->quantity = $request->input('quantity');
        $quote->material = $request->input('material');
        $quote->due_date = $request->input('due_date');
        $quote->company_name = $request->input('company_name');
        $quote->save();

        $counter = 0;
        foreach ($request->file('files') as $file) {
            $path = $file->storeAs(
                'quote-requests/' . str_replace(' ', '_', $quote->company_name) . '/' . $quote->id,
                $file->getClientOriginalName()
            );
            $quote->files()->create([
                'quote_id' => $quote->id,
                'file_uri' => $path
            ]);
            $counter++;
        }
        if($counter === 0)
        {
            return Response::json(['files' => 'No files were received. Please try again'], 400);
        }

        return Response::json(['success' => 'Thank you. Your request has been received.'], 200);
    }

Any ideas why it is duplicating records for each file sent via the form?

Apr
12
3 weeks ago
Activity icon

Replied to File Upload

I changed my validation to both of the following:

'file' => ['required']
'files' => ['required']

The first returned an error that the file field was required. The second returned another error:

Symfony\Component\Mime\Exception\InvalidArgumentException: The "" file does not exist or is not readable. in file /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/symfony/mime/FileinfoMimeTypeGuesser.php on line 50

Apr
08
1 month ago
Activity icon

Replied to File Upload

Here is my view

@extends('layouts.base')

@section('title', 'Request A Quote For Your Next CNC Project')
@section('keywords', 'quote, cam project, cnc project, contract manufacturing, custom prototype')
@section('description', 'Let Buck\'s CNC Machining help you with your next CNC project. Request a quote today.')

@section('hero-content')
    <div class="hero-cta">
        <h1 class="hero-main-line">LET US</h1>
        <h4 class="hero-secondary-line">WIN YOUR BUSINESS</h4>
        <p>Several companies have put their trust in us and have been pleased with the result.</p>
        <p>We would love the chance to work with you. Please fill out the form below, and our skilled staff will be in contact with you shortly.</p>
    </div>
@endsection

@section('body-content')
    <div class="alert alert-danger hidden form-alert">
        Oops! There were some issues with the information you provided. Please check the feedback below.
    </div>
    <form id="request" method="post" action="{{ route('quote.store') }}" enctype="multipart/form-data">
        <fieldset>
            <legend>CONTACT INFORMATION</legend>
            <div class="first-name form-control-container">
                <label for="first_name">FIRST NAME</label>
                <input type="text" id="first_name" class="form-control" name="first_name" maxlength="35" value="{{ old('first_name') }}"/>
                <div class="invalid-feedback"></div>
            </div>
            <div class="last-name form-control-container">
                <label for="last_name">LAST NAME</label>
                <input type="text" id="last_name" class="form-control" name="last_name" maxlength="50" value="{{ old('last_name') }}"/>
                <div class="invalid-feedback"></div>
            </div>
            <div class="email-address form-control-container">
                <label for="email_address">EMAIL ADDRESS</label>
                <input type="email" id="email_address" class="form-control" name="email_address" maxlength="125" value="{{ old('email_address') }}"/>
                <div class="invalid-feedback"></div>
            </div>
            <div class="phone-number form-control-container">
                <label for="phone_number">PHONE NUMBER</label>
                <input type="tel" id="phone_number" class="form-control" name="phone_number" maxlength="15" value="{{ old('phone_number') }}"/>
                <div class="invalid-feedback"></div>
            </div>
        </fieldset>
        <fieldset>
            <legend>PROJECT INFORMATION</legend>
            <div class="quantity form-control-container">
                <label for="quantity">QUANTITY</label>
                <input type="number" id="quantity" class="form-control" name="quantity" maxlength="5" value="{{ old('quantity') ?? 1 }}"/>
                <div class="invalid-feedback"></div>
            </div>
            <div class="material form-control-container">
                <label for="material">MATERIAL</label>
                <input type="text" id="material" class="form-control" name="material" maxlength="50" value="{{ old('material') }}"/>
                <div class="invalid-feedback"></div>
            </div>
            <div class="due-date form-control-container">
                <label id="due_date">DUE DATE</label>
                <input type="date" id="due_date" class="form-control" name="due_date" maxlength="10" value="{{ old('due_date') }}"/>
                <div class="invalid-feedback"></div>
            </div>
            <div class="company-name form-control-container">
                <label for="company_name">COMPANY NAME</label>
                <input type="text" id="company_name" class="form-control" name="company_name" maxlength="75" value="{{ old('company_name') }}"/>
                <div class="invalid-feedback"></div>
            </div>
        </fieldset>
        <fieldset class="files">
            <legend>FILES</legend>
            <div class="alert alert-danger invalid-feedback"></div>
            <p class="text-left">Acceptable file types include *.3dm, *.asm, *.cam360, *.CATPart, *.CATProduct,
                *.dwg, *.dxf, *.f3d, *.fbx, *.g, .iam, *.ige, *.iges, *.igs, *.ipt, *.neu,
                *.obj, *.prt, *.sab, *.sat, *.skp, *.sldasm, *.sldprt, *.smb, *.smt, *.ste,
                *.step, *.stl, *.stp, *.wire, *.x_b, *.x_t, *.123dx</p>

            <div class="box js">
                <div class="box__input">
                    <input type="file" name="files[]" id="file" class="box__file" data-multiple-caption="{count} files selected" multiple />
                    <label for="file"><strong>Choose a file</strong><span class="box__dragndrop"> or drag it here</span>.</label>
                </div>
            </div>
        </fieldset>
        @csrf
        <input type="submit" class="button w-100 color-primary" value="SEND">
    </form>
@endsection

@section('js')
    @parent
    <script src="{{ asset('js/fileUpload.js') }}"></script>
@endsection
Activity icon

Replied to File Upload

Here is my JS

function clearForm() {
    let errorElement = document.querySelector('.form-alert');
    let fields = form.querySelectorAll('input');
    let containers = form.querySelectorAll('form-control-container');

    errorElement.classList.add('hidden');
    Array.prototype.forEach.call(fields, function (field) {
        field.classList.remove('is-invalid');
    });
    Array.prototype.forEach.call(containers, function (container) {
        let feedback = container.querySelector('.invalid-feedback');
        feedback.style.visibility = 'hidden';
        feedback.innerHTML = '';
    });
}

function displayError(element, message) {
    let alert = document.querySelector('.form-alert');
    let className = element.replace('_', '-').replace(/\.[0-9]+/g, '');
    let parent = document.querySelector('.' + className);
    let input = parent.querySelector('input');
    let feedback = parent.querySelector('.invalid-feedback');

    alert.classList.remove('hidden');
    input.classList.add('is-invalid');
    feedback.style.visibility = 'visible';
    feedback.style.display = 'inline-block';
    feedback.innerHTML = message;
}

function displaySuccess(message) {
    let formSuccess = document.querySelector('.form-alert');
    formSuccess.classList.remove('alert-danger').add('alert-success');
    formSuccess.innerHTML = message;
}

function scrollToFormTop() {
    document.documentElement.scrollTop = window.innerHeight;
}

function showFiles(files)
{
    label.textContent = files.length > 1 ? (input.getAttribute('data-multiple-caption') || '').replace('{count}', files.length) : files[0].name;
}

form = document.querySelector('#request');
var input = form.querySelector('input[type="file"]');
var label = form.querySelector('label[for="file"]');

input.style.background = '#cc0000';
input.addEventListener('change', function (e) {
    droppedFiles = e.target.files;
    console.log(droppedFiles);
    showFiles(e.target.files);
});

form.addEventListener('submit', function (e) {
    e.preventDefault();

    var ajax = new XMLHttpRequest();
    var data = new FormData(this);

    ajax.open(this.getAttribute('method'), this.getAttribute('action'), true);

    ajax.onload = function () {
        if (ajax.status >= 200 && ajax.status < 400) {
            var data = JSON.parse(ajax.responseText);
            scrollToFormTop();
            displaySuccess(data.success);
        } else {
            scrollToFormTop();
            let errors = JSON.parse(ajax.responseText);
            for (let key in errors) {
                displayError(key, errors[key]);
            }
        }
    };

    ajax.onerror = function () {
        alert('Error. Please, try again!');
    };

    ajax.send(data);
});
Apr
01
1 month ago
Activity icon

Started a new Conversation File Upload

I have a form that is meant to upload multiple files via AJAX. The JSON response that is returned just says "The files.x failed to upload". Here is my controller that handles the request:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Quote;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;

class QuoteRequestController extends Controller
{
    public function index()
    {
        return view('quote.index', ['pageIdentifier' => 'quote']);
    }

    public function store(Request $request)
    {
        $validInput = Validator::make($request->all(), [
            'first_name' => ['required', 'string', 'max:35'],
            'last_name' => ['required', 'string', 'max:50'],
            'email_address' => ['required', 'email:rfc,dns', 'max:125'],
            'phone_number' => ['required', 'string', 'max:15', 'regex:/^[+]*[0-9]*\s*[(]*[0-9]{3}[)]*[\s\.\-]*[0-9]{3}[\.\-]*[0-9]{4}$/'],
            'quantity' => ['required', 'integer','min:1'],
            'material' => ['required', 'string', 'max:50'],
            'due_date' => ['required', 'after:today'],
            'company_name' => ['required', 'string', 'max:75'],
            'files.*' => ['required']
        ]);

        if($validInput->fails())
        {
            return Response::json($validInput->errors(), 400);
        }

        $quote = new Quote;
        $quote->first_name = $request->input('first_name');
        $quote->last_name = $request->input('last_name');
        $quote->email_address = $request->input('email_address');
        $quote->phone_number = $request->input('phone_number');
        $quote->quantity = $request->input('quantity');
        $quote->material = $request->input('material');
        $quote->due_date = $request->input('due_date');
        $quote->company_name = $request->input('company_name');
        $quote->save();

        if($request->hasfile('files'))
        {
            $counter = 0;
            foreach ($request->file('files') as $file) {
                $path = $file->storeAs('quote-requests', $request->input('company_name') . $counter . '.' . $file->extension());
                return Response::json(['path' => $path], 400);
                $quote->files()->create([
                    'quote_id' => $quote->id,
                    'file_uri' => $path
                ]);
            }
        } else
        {
            return Response::json(['files' => 'No files were received. Please try again'], 400);
        }

        return Response::json(['success' => 'Thank you. Your request has been received.'], 200);
    }
}

The error isn't one that I pass back, so Laravel must be automatically generating it. How can I work around this error?

Mar
29
1 month ago
Activity icon

Replied to Multiple File Upload Fails

Hey, the conversation has to start somewhere. I have run composer install. It tells me that I have nothing to install or update.

My problem seems centered around the file type that I'm uploading. I need to only accept CAD files. The code borrowed from Symphony in Laravel seems to be applying a .bin extension to the uploaded files. I'm having trouble forcing my controller to use the file's original extension.

if($request->hasfile('files'))
        {
            $counter = 0;
            foreach ($request->file('files') as $file) {
                //$path = $file->storeAs('quote-requests', $file->getClientOriginalName());
                //$path = Storage::putFile('quote-requests', $file->getClientOriginalName());
                $path = $file->storeAs('quote-requests', $request->input('company_name') . $counter . $file->extension());
                return Response::json(['path' => $path], 400);
                $quote->files()->create([
                    'quote_id' => $quote->id,
                    'file_uri' => $path
                ]);
            }
        } else
        {
            return Response::json(['files' => 'No files were received. Please try again'], 400);
        }

Even with this code, the file extension gets garbled from .SLDPRT to .bin.

Activity icon

Started a new Conversation Multiple File Upload Fails

Whenever I try to upload multiple (or any files, for that matter) via an HTML form, I get the following error:

Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException: The file "164259_2018REF.SLDPRT" does not exist in file /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/symfony/http-foundation/File/File.php on line 36

#0 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php(256): Symfony\Component\HttpFoundation\File\File->__construct()
#1 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemManager.php(383): Illuminate\Filesystem\FilesystemAdapter->putFile()
#2 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Illuminate\Filesystem\FilesystemManager->__call()
#3 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/app/Http/Controllers/QuoteRequestController.php(52): Illuminate\Support\Facades\Facade::__callStatic()
#4 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): App\Http\Controllers\QuoteRequestController->store()
#5 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\Routing\Controller->callAction()
#6 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Route.php(254): Illuminate\Routing\ControllerDispatcher->dispatch()
#7 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Route.php(197): Illuminate\Routing\Route->runController()
#8 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(693): Illuminate\Routing\Route->run()
#9 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\Routing\Router->Illuminate\Routing\{closure}()
#10 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#11 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Routing\Middleware\SubstituteBindings->handle()
#12 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#13 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle()
#14 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#15 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\View\Middleware\ShareErrorsFromSession->handle()
#16 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#17 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(63): Illuminate\Session\Middleware\StartSession->handleStatefulRequest()
#18 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Session\Middleware\StartSession->handle()
#19 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#20 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle()
#21 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#22 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Cookie\Middleware\EncryptCookies->handle()
#23 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#24 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(695): Illuminate\Pipeline\Pipeline->then()
#25 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(670): Illuminate\Routing\Router->runRouteWithinStack()
#26 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(636): Illuminate\Routing\Router->runRoute()
#27 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(625): Illuminate\Routing\Router->dispatchToRoute()
#28 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(166): Illuminate\Routing\Router->dispatch()
#29 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}()
#30 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#31 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#32 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#33 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#34 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#35 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle()
#36 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#37 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()
#38 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/fruitcake/laravel-cors/src/HandleCors.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#39 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\Cors\HandleCors->handle()
#40 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#41 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\Proxy\TrustProxies->handle()
#42 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#43 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(141): Illuminate\Pipeline\Pipeline->then()
#44 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#45 /mnt/c/Users/eric.drake/Documents/Sites/dev.buckscnc.com/public/index.php(52): Illuminate\Foundation\Http\Kernel->handle()
#46 {main}

I'm at a loss on this one. Does anyone have any experience with this and care to weigh in?

Mar
17
1 month ago
Activity icon

Replied to Bootstrap JS Isn't Being Included

Could you tell me which file(s) are responsible for importing new packages into public/js/app.js?

Activity icon

Replied to Eloquent Subqueries

Yep, that's what I needed. Thanks for your help.

Activity icon

Started a new Conversation Eloquent Subqueries

I would like to find the description value for a given document. The description is stored as a variable value in another table. The relationship between the tables has been defined in my models:

Document

<?php

namespace App\PDM;

use App\DoubleL\Application\Constants;
use Illuminate\Database\Eloquent\Model;

class Document extends Model
{
    protected $connection = 'engineering';
    protected $table = 'Documents';
    protected $primaryKey = 'DocumentID';

    public static function exists($partNumber)
    {
        return Document::where('Filename', $partNumber . Constants::SOLIDWORKS_PART_EXTENSION)->first() ? true : false;
    }

    public function variableValues()
    {
        return $this->hasMany('App\PDM\VariableValue', 'DocumentID');
    }
}

VariableValue

<?php

namespace App\PDM;

use Illuminate\Database\Eloquent\Model;

class VariableValue extends Model
{
    protected $connection = 'engineering';
    protected $table = 'VariableValue';

    public function document()
    {
        return $this->belongsTo('App\PDM\Document', 'DocumentID');
    }

    public function variable()
    {
        return $this->belongsTo('App\PDM\Variable', 'VariableID');
    }
}

The query I would like to reproduce is as follows:

SELECT v1.DocumentID, v1.RevisionNo, v1.VariableID, v1.ValueText
from VariableValue v1 join (
    select DocumentID, max(RevisionNo) as RevisionNo
	from VariableValue
	where DocumentID=223865
	group by DocumentID
) v2 on v1.DocumentID=v2.DocumentID and v1.RevisionNo=v2.RevisionNo
where v1.VariableID=47

(The description variable ID is 47).

How can I make these models return the result that this query produces?

Activity icon

Replied to Bootstrap JS Isn't Being Included

I'm running Laravel 8.30.1. The CSS for Bootstrap is included through the public/css/app.css file (I can search for Bootstrap classes, and they appear in the file). I'm not sure why the Bootstrap JS isn't working as well.

Activity icon

Started a new Conversation Bootstrap JS Isn't Being Included

None of the JS functions of the Bootstrap components of my application are working. (Bootstrap CSS works fine). I assume that all of Bootstrap's dependencies haven't been properly included.

I ran php artisan ui bootstrap and npm install && npm run dev. I included public/css/app.css and public/js/app.js in the HTML of my base layout. What else am I missing?

Also, by running these commands, FontAwesome has disappeared from my app.css file. Why would it have been affected?

Feb
18
2 months ago
Activity icon

Awarded Best Reply on Implementing Policies On Many-To-Many Relationships

My biggest hurdle to overcome was getting the authorize method to accept all of the arguments that I needed for my policy logic. Whenever I would pass an array with more than one index in the second parameter, all but the first index would be truncated. To fix this, I passed the model class as the first index, then all other arguments would be preserved.

$this->authorize('updateGroupAbilities', [Group::class, $group, $abilities]);

I declared the updateGroupAbilities method in the GroupPolicy class like so:

public function updateGroupAbilities(User $user, Group $group, $abilities)

With those three arguments, I could define the logic that would prevent anyone other than the superAdmin from editing the admin group abilities or from assigning admin-level abilities to standard-user-level groups.

Thank you for working through the problem with me. I appreciate it.

Activity icon

Replied to Add Custom Attribute To Eloquent Model

As far as I know, nothing. I am running Laravel 6, if that changes anything.

Activity icon

Replied to Add Custom Attribute To Eloquent Model

getAttributes returns this:

array:4 [▼
  "ROWID" => "796093"
  "USER_ID" => "ARODRIGUEZ"
  "MACHINE_ID" => "776B67747A7D7562687B7D707B747487"
  "LAST_ACTIVITY" => "2021-02-17 12:15:13.303"
]

toArray only returns this:

array:1 [▼
  "idle_time" => "20 hours 44 minutes ago"
]

I'd be doing great if I could have all five indexes and values together. Do I have to merge the two arrays, or does Laravel had this more elegantly?

Feb
17
2 months ago
Activity icon

Replied to Add Custom Attribute To Eloquent Model

So, I added these lines of code to the VisualLogins model:

public $appends = ['idle_time'];

public function getIdleTimeAttribute()
{
    return $this->idleTimeReadable();
}

I can access the new attribute with $result->idle_time, but it does appear in the $headers array when I run the following:

$headers = array_keys($results->get(0)->getAttributes());

Because it isn't included in this array, it doesn't appear in the data table. Is there something else that I'm missing?

Activity icon

Started a new Conversation Add Custom Attribute To Eloquent Model

I have a model, VisualLogin, that retrieves the following columns from a database; ROWID, USER_ID, MACHINE_ID, and LAST_ACTIVITY. I have created a custom attribute named idle_time that I would like to display in a data table.

Here is the VisualLogin model:

<?php

namespace App;

use Carbon\Carbon;
use Carbon\CarbonInterface;
use Carbon\CarbonTimeZone;
use Illuminate\Database\Eloquent\Model;

class VisualLogin extends Model
{
    protected $connection = 'vmfg';
    protected $table = 'LOGINS';
    protected $primaryKey = 'ROWID';

    public function getIdleTimeAttribute()
    {
        return $this->idleTimeReadable();
    }

    private function idleTimeReadable()
    {
        $diff = $this->convertMSTtoUTC($this->last_activity);
        return $diff->diffForHumans(Carbon::now(), CarbonInterface::DIFF_RELATIVE_TO_NOW, false, 2);
    }

    private function idleTimeInSeconds()
    {
        $diff = $this->convertMSTtoUTC($this->last_activity);
        return $diff->diffInSeconds(Carbon::now(), true);
    }

    private function convertMSTtoUTC($timestamp)
    {
        $diff = new Carbon($timestamp, new CarbonTimeZone('America/Boise'));
        return $diff->setTimezone('UTC');
    }

    public static function getUniqueLogins()
    {
        return VisualLogin::query()
            ->select('LOGINS.ROWID as rowid', 'LOGINS.USER_ID as user_id', 'LOGINS.MACHINE_ID as machine_id', 'LOGINS.LAST_ACTIVITY as last_activity')
            ->joinSub(VisualLogin::query()
                ->select('USER_ID', 'MACHINE_ID')
                ->selectRaw('MAX(LAST_ACTIVITY) as LAST_ACTIVITY')
                ->groupBy('USER_ID', 'MACHINE_ID'), 'L2', function ($join) {
                $join->on('L2.USER_ID', '=', 'LOGINS.USER_ID');
                $join->on('L2.MACHINE_ID', '=', 'LOGINS.MACHINE_ID');
                $join->on('L2.LAST_ACTIVITY', '=', 'LOGINS.LAST_ACTIVITY');
            })
            ->orderBy('LOGINS.LAST_ACTIVITY')
            ->get();
    }
}

Here is the data table component:

@php
    //$omit is an array of column headings to not display
    if(!isset($omit))
    {
        $omit = [];
    }
    //$actions is an array that determines the button options for each table row
    if(!isset($actions))
    {
        $actions = [];
    }
    //$routes is an array of columns to be treated as links
    if(!isset($routes))
    {
        $routes = [];
    }
    if(count($results) > 0)
    {
        if(is_a($results, 'Illuminate\Database\Eloquent\Collection'))
        {
            $headers = array_keys($results->get(0)->getAttributes());
        }
        else
        {
            $headers = array_keys(get_object_vars($results->get(0)));
        }
    }
    else
    {
        $headers = [];
    }
@endphp

@if(count($headers) > 0)
    <div class="table-responsive-md action-table not-sortable">
        <table class="table table-striped table-bordered">
            <thead>
            <tr>
                @for($i=0;$i<count($headers);$i++)
                    @if(!in_array($headers[$i], $omit))
                        <th>
                            <div class="result-table-header-container">
                                <div class="result-table-header-label">
                                    {{ strtoupper(str_replace('_', ' ', $headers[$i])) }}
                                </div>
                                <div class="result-table-header-icons">
                                    <div class="result-table-header-sort-asc">
                                        <a href="{{ request()->fullUrlWithQuery(['sortBy' => $headers[$i], 'sort' => 'asc']) }}" class="sort-icon color-darkest-grey" data-sortby="{{ $headers[$i] }}" data-sort="asc">
                                            <i class="fas fa-caret-up"></i>
                                        </a>
                                    </div>
                                    <div class="result-table-header-sort-desc">
                                        <a href="{{ request()->fullUrlWithQuery(['sortBy' => $headers[$i], 'sort' => 'desc']) }}" class="sort-icon color-darkest-grey" data-sortby="{{ $headers[$i] }}" data-sort="desc">
                                            <i class="fas fa-caret-down"></i>
                                        </a>
                                    </div>
                                </div>
                            </div>
                        </th>
                    @endif
                @endfor
                @if(count($actions) > 0)
                <th></th>
                @endif
            </tr>
            </thead>
            @foreach($results as $result)
                <tr>
                    @for($i=0;$i<count($headers);$i++)
                        @if(!in_array($headers[$i], $omit))
                            @if(empty($result->{$headers[$i]}))
                                <td>NA</td>
                            @else
                                @if(array_key_exists($headers[$i], $routes))
                                    <td><a href="{{ route($routes[$headers[$i]], [deriveVariableFromHeader($headers[$i]) => $result->{$headers[$i]}]) }}">{{ $result->{$headers[$i]} }}</a></td>
                                @else
                                    <td>{{ $result->{$headers[$i]} }}</td>
                                @endif
                            @endif
                        @endif
                    @endfor

                    <td>
                        @foreach($actions as $action)
                            @if($action['form_method'] !== 'GET')
                                @include('components.formbutton', [
                                    'route' => $action['route'],
                                    'parameters' => [$action['identifier'] => $result->{$action['identifier']}],
                                    'form_method' => $action['form_method'],
                                    'icon' => 'trash-alt',
                                    'label' => $action['button_label']
                                ])
                            @else
                                @include('components.button', [
                                    'route' => $action['route'],
                                    'parameters' => [ $action['identifier'] => $result->{$action['identifier']} ],
                                    'icon' => 'pen',
                                    'label' => $action['button_label']
                                ])
                            @endif
                        @endforeach
                    </td>
                </tr>
            @endforeach
        </table>
    </div>
@else
    <h2>NO RESULTS</h2>
@endif

$results is a collection of VisualLogins objects. This component doesn't see the idle_time attribute and display it. It only displays what was returned directly from the database. How could I add idle_time so that it would also be returned by the getAttributes() method of the collection?

Feb
12
2 months ago
Activity icon

Replied to Implementing Policies On Many-To-Many Relationships

My biggest hurdle to overcome was getting the authorize method to accept all of the arguments that I needed for my policy logic. Whenever I would pass an array with more than one index in the second parameter, all but the first index would be truncated. To fix this, I passed the model class as the first index, then all other arguments would be preserved.

$this->authorize('updateGroupAbilities', [Group::class, $group, $abilities]);

I declared the updateGroupAbilities method in the GroupPolicy class like so:

public function updateGroupAbilities(User $user, Group $group, $abilities)

With those three arguments, I could define the logic that would prevent anyone other than the superAdmin from editing the admin group abilities or from assigning admin-level abilities to standard-user-level groups.

Thank you for working through the problem with me. I appreciate it.

Activity icon

Replied to Implementing Policies On Many-To-Many Relationships

In this case, I haven't pigeon-holed the users into a single type. I'm hoping to develop functionality similar to what I've implemented in Active Directory. A user can belong to many groups. A group can have many users. Permissions are set on a group level. In this application, though, I want to prevent admins from adding users to the admin group or from adding admin-level permissions to other groups.

If I were to create a single role for a user, wouldn't I still run into this issue if I wanted to authorize admins to only apply certain abilities to a user type?

Feb
11
2 months ago
Activity icon

Started a new Conversation Implementing Policies On Many-To-Many Relationships

My application grants abilities to groups, and users are given permissions by being added to one or more groups. In the admin console of my app, the Edit User form allows admins to assign the user to groups. Using policies, I would like to restrict the groups to which a user can be added without superadmin approval. How can I do that?

Here is my UserPolicy class

<?php

namespace App\Policies;

use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
use App\DoubleL\Application\Constants;

class UserPolicy
{
    use HandlesAuthorization;

    //the super admin cannot be edited or deleted by other admins
    private $superAdmin;

    public function __construct()
    {
        $this->superAdmin = User::where('username', 'bigboss')->first();
    }

    public function viewAny(User $user)
    {
        return $user->groups->contains(Constants::ADMIN_GROUP_ID)
            ? Response::allow()
            : Response::deny('Only members of the ADMIN group are allowed to view users.');
    }

    public function delete(User $user, User $model)
    {
        if($user->is($this->superAdmin))
        {
            return Response::allow();
        } else if($user->groups->contains(Constants::ADMIN_GROUP_ID) && (!$model->is($this->superAdmin)))
        {
            return Response::allow();
        } else
        {
            return Response::deny('You do not have permission to delete the user ' . $model->username);
        }
    }

    public function update(User $user, User $model)
    {
        if($user->is($this->superAdmin))
        {
            return Response::allow();
        } else if($user->groups->contains(Constants::ADMIN_GROUP_ID) && (!$model->is($this->superAdmin)))
        {
            return Response::allow();
        } else
        {
            return Response::deny('You do not have permission to update the user ' . $model->username);
        }
    }
}
Feb
01
3 months ago
Activity icon

Started a new Conversation Return Only Users Who Don't Belong To A Group

In my application, users are assigned to groups, and groups are assigned permissions. I would like to know how many users haven't yet been assigned to a group.

Here is my User model

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'first_name', 'last_name', 'username', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function abilities()
    {
        return $this->groups->map->abilities->flatten()->pluck('key')->unique();
    }

    public function groups()
    {
        return $this->belongsToMany('App\Group', 'user_group');
    }

    public function routeNotificationForMail($notification)
    {
        //when a user is created, send the notification to the admin
        if(is_a($notification,'App\Notifications\UserCreated'))
        {
            return env('ADMIN_EMAIL');
        }
        return $this->email;
    }
}

Here is my Group model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Group extends Model
{
    //public $timestamps = false;

    public function users()
    {
        return $this->belongsToMany('App\User', 'user_group');
    }

    public function abilities()
    {
        return $this->belongsToMany('App\Ability', 'group_abilities');
    }
}

How would I find all of the users who have no groups without querying for all users, looping through them, and counting the number of groups they are assigned to?

Jan
19
3 months ago
Activity icon

Replied to Eloquent Is Passing Invalid Parameters To SQL Queries From A Model

Here is the migration for the models table:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductModels extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('product_models', function (Blueprint $table) {
            $table->string('model_number', 10)->primary();
            $table->tinyInteger('family_id');
            $table->string('description', 40);
            $table->bigInteger('base_machine_feature_id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('product_models');
    }
}

Here is the migration for the model_features table:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateModelFeatures extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('model_features', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('model_number', 10);
            $table->string('description', 100);
            $table->timestamps();
            $table->string('created_by', 40);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('model_features');
    }
}
Activity icon

Replied to Eloquent Is Passing Invalid Parameters To SQL Queries From A Model

Thanks for your reply. I added the line per your suggestion. Eloquent still passes 0 as the model_number value.

Here is the updated store method:

public function store(Request $request)
    {
        $validInput = $this->verifyInput($request);
        $model = new ProductModel();
        $model->model_number = strtoupper($validInput['model_number']);
        $model->description = strtoupper($validInput['description']);
        $model->family_id = $validInput['family_id'];
        $model->created_by = $request->user()->username;

        $model->save();

        $feature = new ModelFeature();
        $feature->model_number = strtoupper($validInput['model_number']);
        $feature->description = strtoupper($validInput['model_number']) . ' BASIC MACHINE';
        $feature->created_by = $request->user()->username;

        $model->features()->save($feature);

        $model->base_machine_feature_id = $feature->id;

        $model->save();

        return redirect()->route('productmodels.index');
    }

Here is the error message:

SQLSTATE[23000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The INSERT statement conflicted with the FOREIGN KEY constraint "model_features_model_number_foreign". The conflict occurred in database "KEYSTONE", table "db_owner.product_models", column 'model_number'. (SQL: insert into [model_features] ([model_number], [description], [created_by], [updated_at], [created_at]) values (0, 901 BASIC MACHINE, eric.drake, 2021-01-19 23:38:46.355, 2021-01-19 23:38:46.355)) 

I was under the impression that the line -- $model->features()->save($feature) -- would inject the model_number value from the ProductModel object. Is that not the case?

Activity icon

Started a new Conversation Eloquent Is Passing Invalid Parameters To SQL Queries From A Model

I have two related models: ProductModel and ModelFeature. When I instantiate a new ProductModel, it should also create a new ModelFeature object and assign the ModelFeature object's ID to the ProductModel object's base_machine_feature_id attribute.

Here is my store and verifyInput methods in the ProductModelsController

public function store(Request $request)
    {
        $validInput = $this->verifyInput($request);
        $model = new ProductModel();
        $model->model_number = strtoupper($validInput['model_number']);
        $model->description = strtoupper($validInput['description']);
        $model->family_id = $validInput['family_id'];
        $model->created_by = $request->user()->username;

        $model->save();

        $feature = new ModelFeature();
        $feature->description = strtoupper($validInput['model_number']) . ' BASIC MACHINE';
        $feature->created_by = $request->user()->username;

        $model->features()->save($feature);

        $model->base_machine_feature_id = $feature->id;

        $model->save();

        return redirect()->route('productmodels.index');
    }

    protected function verifyInput(Request $request)
    {
        return $request->validate([
            'model_number' => ['required', 'string', 'max:10', 'unique:App\Pricebook\ProductModel'],
            'description' => ['required', 'string', 'max:100'],
            'family_id' => ['required', 'integer', 'exists:App\Pricebook\ProductFamily,id']
        ]);
    }

The application throws the following error when trying to save the ModelFeature:

SQLSTATE[23000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The INSERT statement conflicted with the FOREIGN KEY constraint "model_features_model_number_foreign". The conflict occurred in database "KEYSTONE", table "db_owner.product_models", column 'model_number'. (SQL: insert into [model_features] ([description], [created_by], [model_number], [updated_at], [created_at]) values (901 BASIC MACHINE, eric.drake, 0, 2021-01-19 23:01:38.504, 2021-01-19 23:01:38.504)) 

For some reason, Eloquent is passing the value of 0 to the insert query for the model_number. Why would it do that? (You can see that it passes the correct model number in the description field).

Activity icon

Replied to Retrieve Member Properties From Eloquent Collection

I like the idea of creating a member method that returns the properties of the class. If I were to do that, I would want to extend the Model class and add the method to the child class. I would want all of my models to extend this new child class. Is there any way create a model using an Artisan command that would use my custom child class instead of the default Model class?

Jan
15
3 months ago
Activity icon

Started a new Conversation Retrieve Member Properties From Eloquent Collection

I have a component that I would like to reuse with any Eloquent collection.

datatable.blade

@php
if($collection->count() > 0)
{
    $headers = array_keys(get_object_vars($collection->get(0)));
}
@endphp
@if($collection->count() > 0)
<table class="table table-striped">
    <thead>
        <tr>
            @foreach($headers as $header)
            <th>{{ $header }}</th>
            @endforeach
        </tr>
    </thead>
    @foreach($collection as $obj)
        @include('components.pricebook.datarow', ['obj' => $obj])
    @endforeach
@else
    <h2>NO RESULTS</h2>
@endif
</table>

You can see where $headers is instantiated. Is there a more eloquent way to retrieve the member properties of any model in the collection?

Dec
18
4 months ago
Activity icon

Started a new Conversation Using Custom Functions In A Blade Template

I have a Blade template with a function in the @php directive. This doesn't feel like the best place for it. Where should I declare this function to still make it callable in the template?

Dec
15
4 months ago
Activity icon

Started a new Conversation Capture Path Info From The Request In The Session

I want to capture each path that a user requests in the session. I thought that the best place to do this would be from the public/index.php file. Here is what I tried:

public/index.php

<?php

/**
 * Laravel - A PHP Framework For Web Artisans
 *
 * @package  Laravel
 * @author   Taylor Otwell <[email protected]>
 */

define('LARAVEL_START', microtime(true));

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/

require __DIR__.'/../vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__.'/../bootstrap/app.php';

/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
dump(session()->all());
if(session()->has('breadcrumb'))
{
    session('breadcrumb')->addPage($request->getPathInfo());
}
else
{
    dump("created breadcrumb");
    $breadcrumb = new App\DoubleL\Application\NavigationBreadcrumb();
    session(['breadcrumb' => $breadcrumb]);
    session('breadcrumb')->addPage($request->getPathInfo());
}
dd(session()->all());
$response->send();

$kernel->terminate($request, $response);

Here is the NavigationBreadcrumb class:

<?php

namespace App\DoubleL\Application;

class NavigationBreadcrumb
{
    protected $flow;

    public function __construct()
    {
        $this->flow = collect();
    }

    public function addPage($routeName)
    {
        $this->flow->push($routeName);
    }

    public function getPreviousPage()
    {
        return $this->flow->last();
    }
}

The session only ever stores the information for the most recent request. How can I make it save every path the user visits?

Dec
14
4 months ago
Activity icon

Started a new Conversation More Intuitive Url->previous() Functionality

In my application, there are several interconnected reports. For example, the Work Order Information report has links to the requested work order's bill of materials or its corresponding customer order. The flow of web traffic is as follows:

Work Order Information Form -> Work Order Information -> Bill of Materials

Once the user submits a form, the resulting pages have a Back button to redirect back to the form. The Back button is is a component template of its own with a link to url->previous. In the case of the traffic flow I described, a user gets caught in a loop between the Work Order Information and Bill of Materials pages.

Is there another helper function like url->previous that keeps track of more than just the previous page visited? Apart from hard coding the route name into the Back Button component, is there another way to always have the back button on the Work Order Information report link back to its form?

Dec
11
4 months ago
Activity icon

Replied to Select From A Subquery Using Query Builder

I figured it out.

$partsSubquery = DB::connection('vmfg')
                ->table('REQUIREMENT as r')
                ->join('PART as p', 'p.ID', '=', 'r.PART_ID')
                ->join('PART_SITE as ps', 'p.ID', '=', 'ps.PART_ID')
                ->select('p.ID as PART_NUMBER', 'p.DESCRIPTION', 'ps.UNIT_PRICE')
                ->where('r.WORKORDER_BASE_ID', '=', $validInput['workorder_number'])
                ->orderBy('ps.UNIT_PRICE', 'desc')
                ->limit(20);

$partsQuery = DB::connection('vmfg')
                ->query()
                ->fromSub($partsSubquery, 'PE')
                ->select('PART_NUMBER', 'DESCRIPTION', 'UNIT_PRICE');

if(isset($validInput['sortBy']))
            {
                $partsQuery->orderBy($validInput['sortBy'], $validInput['sort']);
            }
            else
            {
                $partsQuery->orderBy('UNIT_PRICE', 'desc');
            }
$partsQuery->get()

I noticed that no one chimed in on this. Am I barking up the wrong tree with Query Builder? Is this better done using Eloquent?

Activity icon

Started a new Conversation Select From A Subquery Using Query Builder

I have a data table that I want to allow users to sort by whichever column they choose. One of these data tables is supposed to show the 20 most expensive parts in a workorder. Here is the query I'm trying to duplicate using Query Builder:

select PART_NUMBER, DESCRIPTION, UNIT_PRICE
from (
    select top 20 p.ID as PART_NUMBER, p.DESCRIPTION, ps.UNIT_PRICE
	from requirement r 
	join PART p on p.ID=r.PART_ID
	join PART_SITE ps on p.ID=ps.PART_ID
	where r.WORKORDER_BASE_ID=?
	order by ps.UNIT_PRICE desc
)
order by DESCRIPTION desc

How do I select from a subquery?

Dec
10
4 months ago
Activity icon

Replied to Add Parameters To Current URL's Query String

Worked perfectly! Thanks for the assist.

Activity icon

Started a new Conversation Add Parameters To Current URL's Query String

I have a table used on several pages on my application. I would like users to be able to select a column to sort. Is there a better way to link to the same page with additional query parameters than this?

<a href="{{ url(URL::full() . '&sortBy=YourMama&sort=asc' }}"></a>
Dec
09
4 months ago
Activity icon

Awarded Best Reply on Include A Component With @yield Sections

I figured it out. I needed to use the @component directive instead of @include. The solution is posted below:

Dashboard

@extends('base')

@section('content')
    <div class="widget-grid">
        @component('components.dashboardwidget', ['icon' => 'users', 'widgetTitle' => 'USERS'])
            @slot('contentBody')
                {{ $userCount }} registered users
            @endslot
            @slot('cta')
                <a href="{{ route('adminuser.index') }}" class="btn btn-light btn-outline-dark">VIEW USERS</a>
            @endslot
        @endcomponent
    </div>
@endsection

DashboardWidget

<div class="dashboard-widget-container">
    <div class="widget gradient-background gradient-border">
        <i class="fas fa-{{ $icon }} widget-icon"></i>
        <h3>{{ $widgetTitle }}</h3>
        <p>{{ $contentBody }}</p>
        {{ $cta }}
    </div>
</div>
Activity icon

Replied to Include A Component With @yield Sections

I figured it out. I needed to use the @component directive instead of @include. The solution is posted below:

Dashboard

@extends('base')

@section('content')
    <div class="widget-grid">
        @component('components.dashboardwidget', ['icon' => 'users', 'widgetTitle' => 'USERS'])
            @slot('contentBody')
                {{ $userCount }} registered users
            @endslot
            @slot('cta')
                <a href="{{ route('adminuser.index') }}" class="btn btn-light btn-outline-dark">VIEW USERS</a>
            @endslot
        @endcomponent
    </div>
@endsection

DashboardWidget

<div class="dashboard-widget-container">
    <div class="widget gradient-background gradient-border">
        <i class="fas fa-{{ $icon }} widget-icon"></i>
        <h3>{{ $widgetTitle }}</h3>
        <p>{{ $contentBody }}</p>
        {{ $cta }}
    </div>
</div>
Activity icon

Started a new Conversation Include A Component With @yield Sections

I'm creating a dashboard with basic widget components. Here is the widget component template:

<div class="dashboard-widget-container">
    <div class="widget gradient-background gradient-border">
        <i class="fas fa-{{ $icon }} widget-icon"></i>
        <h3>{{ $widgetTitle }}</h3>
        @yield('contents')
        @yield('cta')
    </div>
</div>

Here is my dashboard template:

@extends('base')

@section('content')
    <div class="widget-grid">
        @include('components.dashboardwidget', ['icon' => 'users', 'widgetTitle' => 'Users'])
    </div>
@endsection

I would like to include the widget component for any number of widgets on my dashboard. How would I extend the contents and cta sections of the widget component through an @include?

Dec
07
5 months ago
Activity icon

Started a new Conversation Cross-Database Relationships

I'm building an add-on to an existing application. I'm keeping my add-on separate from its parent application by having one database for each. Is it possible to define a relationship between one model class of Database A with another model class that accesses Database B?

Here is an example of what I'm trying to do:

I have a model named Quote. Quotes are stored in the database named Keystone. Quotes belong to a customer. My customer model accesses its data from a database named VMFG. How would I create my relatioship methods in each model to access customer data from the quote model?

Dec
03
5 months ago
Activity icon

Replied to User Created Notification

I ran into a snag with this approach. When a new user is registered, I get the error "Call to undefined method App\Notifications\UserCreated::handle()." I take it that the $listen property is expecting a different type of class than the Illuminate\Notifications\Notification class.

Activity icon

Started a new Conversation User Created Notification

When a new user registers on my site, I would like to receive an email notification. I haven't yet wrapped my mind around how the notification would be triggered. I created a new notification class called UserCreated, and I'm using the User model class that comes with Laravel UI. How do I link these two classes up? What happens when a user registers to my site that I can listen for to trigger the UserCreated notification?

Nov
25
5 months ago
Activity icon

Started a new Conversation Add An Error To A Bag Without Redirecting

I have a form with a text box that accepts one workorder ID per line. In the controller, I want to loop over the input received to verify that each line contains a valid workorder ID. When an invalid workorder is found, I want to add it to the message bag without redirecting until the loop is finished. How can I do that?

Nov
24
5 months ago
Activity icon

Replied to Missing Required Parameters

Your suggestion worked. I have a concern though. Does Laravel have to query the database all over again to reinstantiate the object in the controller?