mankowitz

mankowitz

Member Since 1 Year Ago

Experience Points 880
Experience
Level
Lessons Completed 0
Lessons
Completed
Best Reply Awards 0
Best Answer
Awards
  • Start Your Engines Achievement

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • First Thousand Achievement

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • One Year Member Achievement

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • Two Year Member Achievement

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • Three Year Member Achievement

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • Four Year Member Achievement

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • Five Year Member Achievement

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • School In Session Achievement

    School In Session

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

  • Welcome To The Community Achievement

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • Full Time Learner Achievement

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • Pay It Forward Achievement

    Pay It Forward

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

  • Subscriber Achievement

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • Lifer Achievement

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • Laracasts Evangelist Achievement

    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 Achievement

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • Laracasts Veteran Achievement

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • Ten Thousand Strong Achievement

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • Laracasts Master Achievement

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • Laracasts Tutor Achievement

    Laracasts Tutor

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

  • Laracasts Sensei Achievement

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • Top 50 Achievement

    Top 50

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

20 Jan
1 day ago

mankowitz left a reply on Appended Accessors Are Making Me Slow

But the view doesn't use chiefComplaint either. I pass $ptsByDx to the view like this:

   return view("reports.ptsByDxOutcome")
        ->with('byOutcome', $byOutcome)
        ->with('outcomes', $outcomes)
        ->with('byDx', $ptsByDx)
        ->with('sites', $sites);
```

The view doesn't need it.

mankowitz left a reply on Appended Accessors Are Making Me Slow

I know that chief_complaint is not in my query, so I'm not sure why laravel is doing the lookup. Here is what I did, and it seems to have worked.

Instead of using the model Patient, I just used DB::table('patients'). My rationale is that it wouldn't try to construct a model for each query and so it wouldn't look in the accessors.

So, I replace

 $ptsByDx = Patient::select('diagnosis', DB::raw('count(*) as total')) 

with

 $ptsByDx = DB::table('patients')->select('diagnosis', DB::raw('count(*) as total')) 

mankowitz left a reply on Appended Accessors Are Making Me Slow

The field created_year_month_idx is indexed (it's actually virtual column with a materialized index). The diagnosis field is not indexed, but when I run the query with plain old SQL, it takes only a few miliseconds to execute.

When I look at debugbar, it says that it is running 292 queries for this page. Most of them involve looking at chief_complaint. I want to make it stop looking in that accessor.

mankowitz started a new conversation Appended Accessors Are Making Me Slow

I have a model called Patient which has some appended accessors which are useful for short searches. Unfortunately, when I'm doing larger searches (with 5000+ rows), even in aggregate, it slows to a crawl. Is there any way to tell Laravel NOT to include the accessors?

Here is my code:

class Patient extends Model
{
    use SoftDeletes;
    public $timestamps = true;

    public function assignedTo()
    {
        return $this->belongsTo('App\User', 'assigned_to');
    }

    protected $appends = ['length_of_stay', 'chief_complaint_text'];

    public function getLengthOfStayAttribute()
    {
        if ($this->completed_at) {
            return "";
        } else {
            return intval((time() - strtotime($this->created_at))/60);
        }
    }

    public function getChiefComplaintTextAttribute()
    {
        if (empty($this->chief_complaint_name)) {
            if (!$this->chiefComplaint) return "unk";
            else return $this->chiefComplaint->name;
        } else {
            return $this->chief_complaint_name;
        }
    }
}
```

When I execute the following query, it takes >30 seconds

```
        $ptsByDx = Patient::select('diagnosis', DB::raw('count(*) as total')) 
            ->whereNotNull('diagnosis')       
            ->groupBy('diagnosis')        
            ->whereBetween('created_year_month_idx', [$start,$end])      
            ->orderBy('total', 'desc')      
            ->whereIn('site_id', array_keys($sites)) 
            ->having('total', '>', 1)->get();
```

The only two fields I need from the DB are `diagnosis` and `count(*)` and not any of the attributes that are appended. What can I do?
06 Jan
2 weeks ago

mankowitz left a reply on Collection::toArray() Giving Unexpected Results

Wow! That was it. Thanks.

I guess that's the problem with "intuitive" frameworks. If you don't follow their intuition, things break unexpectedly.

02 Jan
2 weeks ago

mankowitz started a new conversation Collection::toArray() Giving Unexpected Results

I have a model called Outcome which is tied to a database table with four rows, as follows:

Outcome::get()
=> Illuminate\Database\Eloquent\Collection {#3491
     all: [
       App\Outcome {#3498
         id: "EXP",
         name: "Expired",
       },
       App\Outcome {#3494
         id: "OBS",
         name: "Observe",
       },
       App\Outcome {#3515
         id: "VOID",
         name: "VOIDED",
       },
       App\Outcome {#3503
         id: "XFR",
         name: "ED Transfer",
       },
     ],
   }

But when I try to use the toArray() function, the id field becomes 0.

>>> Outcome::get()->toArray()
=> [
     [
       "id" => 0,
       "name" => "Expired",
     ],
     [
       "id" => 0,
       "name" => "Observe",
     ],
     [
       "id" => 0,
       "name" => "VOIDED",
     ],
     [
       "id" => 0,
       "name" => "ED Transfer",
     ],
   ]
23 Nov
1 month ago

mankowitz left a reply on Global Function Not Working In Jobs

@cronix Actually, I think this problem was not what I initially thought. It turns out that the queue worker was an old file. I'm not entirely sure why that made it ignore a global function, but reseting the que worker fixed this as well.

mankowitz left a reply on Laravel Using Stale Files In Production

Cronix-

THAT WAS IT!!!! Thanks so much. I use supervisor, so I had to issue supervisorctl restart all, but now it is working again. That's awesome.

mankowitz started a new conversation Laravel Using Stale Files In Production

I have a laravel project that was generating errors, so I deleted the offending line, pushed the code to the repository, pulled the code onto the production server and retried.... but I'm still getting the exception, referencing the line of code which no longer exists. In the test system, everything works as expected,

  1. I checked the production server, and the most recent code is present.
  2. I did composer dumpautoload
  3. I did php artisan clear-compiled
  4. I did php artisan optimize
  5. I did php artisan cache:clear
  6. I did php artisan route:cache
  7. I did php artisan view:clear
  8. I did php artisan config:cache

But the Whoops handler is still giving me errors on files that have clearly changed. What to do?

mankowitz left a reply on Global Function Not Working In Jobs

@CRONIX - sorry. just being lazy. The case is the same in both places. I'll update the question.

mankowitz started a new conversation Global Function Not Working In Jobs

I have a global logging helper function that I keep in a file called app/helpers/logging.php which includes one function called log_info() as shown below. I am referencing that file from composer.json as shown below.

The problem is that log_info() works throughout my app in various controllers, but it does not work in one of my queue jobs. I get the exception Call to undefined function App\Jobs\log_info(). Clearly, it is looking into the namespace of the Job instead of the global namespace. How do I fix that?

app/helpers/logging.php

use Illuminate\Support\Facades\Log;

function log_info(String $message, $arr = [])
{
    $output = "";
    if (empty($arr)) {
        $output = $message;
    } else {
        $output = $message . ": " . print_r($arr, true);
    }

    Log::info($output);
    if (\App::runningInConsole()) {
        print "LOG: $output\n";
    }
}

composer.json

 "autoload": {
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "psr-4": {
            "App\": "app/"
        },
        "files": [
              "app/Helpers/Logging.php"
        ]
    },
31 Aug
4 months ago

mankowitz started a new conversation How To Know If I Am In A Tinker Shell?

I use tinker for debugging, and use print to see results. However, I only want those statements to execute when I'm using the interactive shell. Is there a boolean to detect if I'm in tinker or not? Something like this:

if (isTinker()) {
   print "debugging information...";
}
12 Aug
5 months ago

mankowitz started a new conversation How To Do Basic Auth For A Single User For Api?

I am setting up an integration between another system and my Laravel App. The other system asks me to provide a username:password pair which it then uses to access my App. What is the best way to achieve this? I don't necessarily want to add this user to my users table, although I could if that would help. This is what I've done so far:

In web.php: Route::post('/PCC/webhook', '[email protected]');

In PointClickCareController.php: public function handleWebhook(Request $request) { $header = $request->header('Authorization'); Log::info("webhook header: " . $header); $expectedAuthString = base64_encode($this->webhookUser . ":" . $this->webhookPass); Log::info("webhook auth expected: " . $expectedAuthString); if ($header != $expectedAuthString) { Log::info("webhook auth FAILED"); abort(403, 'Unauthorized action.'); }

In my access.log, I can see that the other system is attempting to connect to /PCC/webhook with the correct username, but none of the Log data is showing up.

05 Jun
7 months ago

mankowitz started a new conversation Where Is The Best Place To Put Functions That Create A Model And Save It, Such As Auditing?

I am making an auditing Model, and I was tinkering with the idea of putting the auditing commands within the model (spoiler alert: it doesn't work). I was wondering what the best way of doing this is.

I was thinking that I could encapsulate the whole thing in the model and, from a controller, I could call it like this

Audit::patientAction(34,'delete')'

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\User;

class Audit extends Model
{
    public function patientAction($patient_id, $action) {
        $a = new self();
        $a->user_id = Auth::user()->id;
        $a->patient_id = $patient_id;
        $a->action = $action;
        $a->ip = Request::ip();
        $a->save();
    }

    public function userAction($action) {
        $this->patientAction(null, $action);
    }

    public function login() {
        $this->userAction(null, "Login");        
    }
}
16 May
8 months ago

mankowitz left a reply on GroupBy() And Count(): What Is The Laravel Way?

@Swaz - Thanks for your help. I already have the one-to-many relations set in the model definitions, but you pointed me in the right direction using withCount()

@Vilfago - Thanks for your help. I used withCount() instead of with() to get the count. Also, I found that get(['id', 'name']) didn't actually limit the output. I had to put in a select(['name']) command.

My final command:

Site::where('medical_director_id', $id)->select(['name'])
    ->withCount(['patients' => function ($q) use($from, $to) { 
        $q->whereBetween('created_at', [$from, $to]);                
    }])->get();

mankowitz started a new conversation GroupBy() And Count(): What Is The Laravel Way?

I have two tables.

patients id site_id

sites id

and they are linked so ( patients.site_id = sites.id )

I want to figure out how many patients there are for each site.

In SQL, I can make a query like this

SELECT sites.NAME, 
       Count(*) 
FROM   sites 
       LEFT JOIN patients 
              ON ( patients.site_id = sites.id ) 
WHERE  patients.site_id IN (SELECT id 
                            FROM   sites 
                            WHERE  medical_director_id = 35) 
       AND patients.created_at BETWEEN 20080101 AND 20200101 

The result is something like this: site | count(*) --- | --- | --- Home1 | 23 Home2 | 0

And I'd like to do the laravel thing, so I start with this:

            Patient::whereBetween('created_at', [$from, $to])
        ->whereIn('site_id', Site::where('medical_director_id', $id)->select(['id']))
        ->groupBy('site_id')

But I can't figure out how to use count() and still get the aggregation. What should I do?

03 Apr
9 months ago

mankowitz left a reply on Getting A Child Of Child Relation

Is there a way to restrict the number of fields that are generated in both the parent and the child relation? For example, I want

provider:name reporter:name site:name patient:first_name,last_name

When I do this,

Complaint::whereNull('resolved_at')->with('provider', 'reporter', 'patient.site')->get();

I get the whole record for provider, reporter, patient and site. I can limit those with

However, when I try this:

>>> Complaint::whereNull('resolved_at')->with('provider:id,name', 'reporter:id,name', 'patient:id,first_name', 'patient.site:name,id')->get();
=> Illuminate\Database\Eloquent\Collection {#1421
     all: [
       App\Complaint {#1392
         id: 1,
         reported_by: 7,
         created_at: "2018-03-27 04:59:56",
         updated_at: "2018-03-27 04:59:56",
         patient_id: 4,
         source: "patient",
         problem: "Medicine made patient itchy",
         provider_id: 2,
         resolution: null,
         resolved_by: null,
         resolved_at: null,
         provider: App\User {#1418
           id: 2,
           name: "Scott",
         },
         reporter: App\User {#1420
           id: 7,
           name: "External NH Two",
         },
         patient: App\Patient {#1406
           id: 4,
           first_name: "Patient",
           site: null,  // I WANT THIS TO HAVE DATA.
         },
       },
     ],
   }

mankowitz started a new conversation Getting A Child Of Child Relation

I have three tables which are related.

A site has many patients which have many complaints. Here are abbreviated models.

class Site extends Model
{
    public function patients() 
    {
        return $this->hasMany('App\Patient');
    }
}

patient:

class Patient extends Model
{

    public function site()
    {
        return $this->belongsTo('App\Site');
    }

    public function complaints()
    {
        return $this->hasMany('App\Complaint');
    }
}

And finally, Complaint

class Complaint extends Model
{
    public function patient()
    {
        return $this->belongsTo('App\Patient');
    }

    public function site()
    {
        return $this->patient->site;
    }
}

So, my problem is that when I query complaints, I want to be able to get the site that the patient was in when that was generated.

Complaint::whereNull('resolved_at')->with('site')->get()

Gives me this:

Illuminate\Database\Eloquent\RelationNotFoundException with message 'Call to undefined relationship [site] on model [App\Complaint].'

One way to workaround was to add this to Complaint.php:

    protected $appends = ['site']; 

    public function getSiteAttribute()
    {
        return $this->patient->site;
    }

Which gives me this:

>>> Complaint::whereNull('resolved_at')->first()
=> App\Complaint {#211
     id: 1,
     reported_by: 7,
     patient_id: 4,
     problem: "Medicine made patient itchy",
     provider_id: 2,
     resolved_by: null,
// NOTE THAT site IS MISSING!!!
   }

Surprisingly, however, this does work:

>>> Complaint::whereNull('resolved_at')->first()->site
=> App\Site {#217
     id: 3,
     name: "Nursing Home 3 (pro)",
     site_info: null,
   }

So, what is the best way to make sure that site is listed in the reply?

17 Mar
10 months ago

mankowitz started a new conversation Multiple Subqueries

I have a rather complex query. How could I write this in eloquent?

SELECT def.shortcut, 
       COALESCE(usr.phrase_text, grp.phrase_text, def.phrase_text) 
FROM   (SELECT * 
        FROM   phrases2 
        WHERE  username IS NULL 
               AND groupname IS NULL) def 
       LEFT JOIN (SELECT * 
                  FROM   phrases2 
                  WHERE  groupname = 'group1') grp 
              ON grp.shortcut = def.shortcut 
       LEFT JOIN (SELECT * 
                  FROM   phrases2 
                  WHERE  username = 'user1') usr 
              ON usr.shortcut = def.shortcut 
ORDER  BY def.shortcut ASC
01 Mar
10 months ago

mankowitz left a reply on Use $on() In Another Component

@bobbybouwmann -

(sorry to ask so many questions) What is the benefit of creating another vue instance to be an EventBus? Specifically, why do

EventBus.$on(...)

when you could just do

this.$on(...)
26 Feb
10 months ago

mankowitz started a new conversation Where Do I Keep JQuery Plugins

I have a jQuery plugin that I'd like to use in my Laravel 5.5 / Vue.js site.

https://github.com/ichord/At.js/

I could download the file and put it somewhere in the Laravel tree. resources/assets/js seems like the most appropriate.

Really, however, I'd like some sort of tool to download the files and update them when bugfixes come out. Bower or Composer or something like that.

OK, so once I've downloaded the file, I need to make sure that it gets loaded into my vuejs component. How is this done? Do I need to have mix minify it?

I have found many fragmented solutions online, but I am really looking for a best common practice.

17 Feb
11 months ago

mankowitz left a reply on __toString() Must Not Throw An Exception, Caught Illuminate\Database\Eloquent\JsonEncodingException:

OK, so I've had some time to analyze the problems and this is the solution that I came up with:

  1. json_encode() fails when there are 8-bit characters in the string. You'd think that it could encode them somehow into 7-bits but it just fails. That was the reason for the initial error.

  2. The curly braces do automatically call json_encode or something similar. For me, the following were equivalent: <notes-editor :patient="{{ json_encode($pt) }}"> and <notes-editor :patient="{{ $pt }}">

  3. My vue errors were coming from a syntax error in my template. Specifically I had forgotten to close a <script> tag. Once I closed it, just about everything started working. It is quite unfortunate that vuejs does not provide more meaningful error messages.

15 Feb
11 months ago

mankowitz left a reply on __toString() Must Not Throw An Exception, Caught Illuminate\Database\Eloquent\JsonEncodingException:

I keep getting false when I use json_encode().

I also get false with this:

json_encode(Patient::with('site', 'notes', 'followUps')->find(1))

and this:

json_encode(Patient::with('site', 'notes', 'followUps')->find(1)->toArray())

mankowitz left a reply on __toString() Must Not Throw An Exception, Caught Illuminate\Database\Eloquent\JsonEncodingException:

I could do it with an ajax request, but I am confused by the error message. Why is vue concerned about an extra comma. Where is that comma comng from?

12 Feb
11 months ago

mankowitz left a reply on __toString() Must Not Throw An Exception, Caught Illuminate\Database\Eloquent\JsonEncodingException:

@bobbybouwmann - Thanks!

I though that the {{ }} was supposed to automatically convert to json.

@tykus - Thanks that is much cleaner.

So, now I'm gettting this error from vue.js

Vue warn]: Failed to generate render function:

SyntaxError: Unexpected token , in

with(this){return _c('div',{attrs:{"id":"app"}},[_m(0,false,false),_v(" "),_c('div',{staticClass:"container"},[_c('h2',[_v("Edit Patient Data for One, Patient")]),_v(" "),_c('div',{staticClass:"panel-group"},[_c('div',{staticClass:"panel panel-default"},[_c('div',{staticClass:"panel-heading"},[_v("Notes")]),_v(" "),_c('div',{staticClass:"panel-body"},[_v("\n                 \n                notes\n                "),_m(1,false,false),_v(" "),_c('record',{attrs:{"patientid":"1"}})],1),_v(" "),_c('div',[_c('notes-editor',{attrs:{"patient":,"notes":}})],1)]),_v(" "),_c('div',{staticClass:"panel panel-default"},[_c('div',{staticClass:"panel-heading"},[_v("Follow-Ups")]),_v(" "),_c('div',{staticClass:"panel-body"},[_c('follow-up-editor',{attrs:{"fups":[{"id":22,"author_id":3,"task":"order ;a new walker","completed_by":null,"completed_at":null,"created_at":"2018-02-11 04:37:31","updated_at":"2018-02-11 04:37:31","deleted_at":null,"patient_id":1},{"id":23,"author_id":3,"task":"cancel party","completed_by":null,"completed_at":null,"created_at":"2018-02-11 04:44:39","updated_at":"2018-02-11 04:44:39","deleted_at":null,"patient_id":1}],"maycomplete":"1","mayedit":"1","patientid":"1"}})],1)]),_v(" "),_m(2,false,false),_v(" "),_c('div',{staticClass:"panel panel-default"}),_v(" "),_m(3,false,false),_v(" "),_c('chart-editor',{ref:"charteditor"})],1)])])}


(found in <Root>)
warn @ app.js:32411
compileToFunctions @ app.js:42354
Vue.$mount @ app.js:42517
Vue._init @ app.js:36370
Vue @ app.js:36455
(anonymous) @ app.js:1110
__webpack_require__ @ app.js:20
(anonymous) @ app.js:1074
__webpack_require__ @ app.js:20
(anonymous) @ app.js:63
(anonymous) @ app.js:66

mankowitz left a reply on Controlling Child From A Parent

Also, you could identify the child component with a ref and then just access its methods.

<parent-component>
  <child-component ref="child1"></child-component>
</parent-component>

And then, in the parent's methods, you could do this

this.$refs.child1.reset();

mankowitz left a reply on How Better Call Components

@tykus - In the parent component, where do you register the children? In the mounted method?

mankowitz left a reply on Use $on() In Another Component

Supplemental question: Why do you need

var that=this;

Doesn't vue.js automatically create a local this var that will be hoisted into any closures?

mankowitz started a new conversation __toString() Must Not Throw An Exception, Caught Illuminate\Database\Eloquent\JsonEncodingException:

I am trying to pass complex objects from laravel to vuejs, but I'm getting the above error. Here are the relevant portions of my code. I'll try to limit to what i need.

The Patient Model

class Patient extends Model
{

    public function assignedTo() 
    {
        return $this->belongsTo('App\User', 'assigned_to');
    }

    public function createdBy() 
    {
        return $this->belongsTo('App\User', 'created_by');
    }

    public function completedBy() 
    {
        return $this->belongsTo('App\User', 'completed_by');
    }

    public function site()
    {
        return $this->belongsTo('App\Site');
    }

    public function notes()
    {
        return $this->hasMany('App\Note');
    }

    public function followUps()
    {
        return $this->hasMany('App\FollowUp');
    }

And the relevant controller

class PatientsController extends Controller
{
       public function edit($id)
    {
        $pt = Patient::where('id', $id)->with('site', 'notes', 'followUps')->get()->first();
        return view('patients.edit', compact('pt'));
    }

Now, if I use blade to iterate through the list, it works fine:

 @if ($pt->notes->count() > 0) 
                notes
                <ol>
                    @foreach($pt->notes as $n) 
                        <li> {{$n->created_at}} {{ $n->noteStatus->note_status_name }}
                            @if ($n->audio_length > 0)
                                <audio controls preload="none">
                                    <source src="/notes/getAudio/{{$n->id}}" type="audio/webm">
                                    Your browser does not support the audio element.
                                </audio>
                                ({{$n->audio_length}}s)
                            @endif 
                            @if ($n->note_text)
                                <a href="#"> Note </a>
                            @endif 
                       </li>
                    @endforeach
                </ol> 
                @endif

However, if I try to pass the object into a vuejs component, like this

<notes-editor :patient="{{$pt}}" :notes="{{$pt->notes}}"></notes-editor>

I get this error:

"Method App\Patient::__toString() must not throw an exception, caught Illuminate\Database\Eloquent\JsonEncodingException: Error encoding model [App\Patient] with ID [1] to JSON: Malformed UTF-8 characters, possibly incorrectly encoded ◀"

Is there any way to find out exactly what field is choking the json encoding? Thanks so much!

09 Dec
1 year ago

mankowitz left a reply on Bringing It All Together (vue, Ajax, Model, Mysql, Bootstrap, Forms, Routes)

Rob and Burl -- Thanks for your replies. Each is useful, but I guess what I'm looking for is a single place where I could define

  1. The database fields (including relationships)
  2. The labels for the form
  3. Whatever stylistic or business logic I want to add

Somehow, magically, laravel will create the Model, the display form, the controller, the validation and the code to store data in the db, gracefully displaying errors if the data isn't right.

Does that exist?

08 Dec
1 year ago

mankowitz started a new conversation Bringing It All Together (vue, Ajax, Model, Mysql, Bootstrap, Forms, Routes)

I'm new to laravel, so this may sound ungrateful, but is there a convenient way to manage the whole stack from presentation of a form to storing it in a database? The way I understand it now, I have to

  1. Create the database with migrations
  2. Create the model (which remains agnostic to the database structure)
  3. Add a route and create a controller to serve the form as well as process its reply
  4. Create an input form view using traditional html elements and bootstrap classes. If validation is used, each element has to have its own way of handling the server-side validation.

So, my question is this: is there a simpler way to create form elements and automatically wire them to a database. Back when I used straight html and php, this was straightforward. now that there are a half dozen levels of indirection, it gets confusing, but not any easier to write or maintain. What am I missing?