chrisgo

chrisgo

Member Since 4 Years Ago

Experience Points
5,590
Total
Experience

4,410 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
42
Lessons
Completed
Best Reply Awards
1
Best Reply
Awards
  • start-engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-session Created with Sketch.

    School In Session

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

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

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

  • subscriber-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

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

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

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

Level 2
5,590 XP
Sep
22
3 weeks ago
Activity icon

Replied to LogDNA With Laravel

Laravel 5.7.x or later

In config/logging.php

add logdna to channels, then add logdna to your stack if you are using that as the default

The main problem you will have is to make sure you have

 'formatter' => 'default', // very important !!!
    'channels' => [

        'stack' => [
            'driver' => 'stack',
            'channels' => ['daily', 'logdna'],  // ###### ADD
            'ignore_exceptions' => false,
        ],


        'logdna' => [
            'driver' => 'monolog',
            'level' => 'debug',
            'handler' => \Zwijn\Monolog\Handler\LogdnaHandler::class,
            'handler_with' => [
                'ingestion_key' => env('LOGDNA_KEY'),
                'hostname' => 'app',
            ],
            'formatter' => 'default',  // ##### does not work without this!
        ],


Aug
08
1 year ago
Activity icon

Replied to How To Import From 1 Xls To 2 Tables, Maatwebsites

That should work -- give it a shot. Try using a file with 1 or 2 rows so you can debug before you run the whole thing

Activity icon

Replied to Sending Base46 Via Ajax To Controller

You have 2 discussions going ...

Activity icon

Replied to How To Get Last Id In Laravel?

After you call ->save();

You can do

$id = $activity->id;
Activity icon

Replied to How To Import From 1 Xls To 2 Tables, Maatwebsites

You will have to add the $id into the array before the next insert

...
$insert['id'] = $id;   // 'id' is the column to match tb_user.id
DB::table('tb_biodoctor')->insert($insert);
Activity icon

Replied to How To Upgrade A Laravel Library From 5.5 To 5.6 Laravel Version.

https://laravel.com/docs/5.6/upgrade

Add this to your composer.json

{
  "require": {
    ...
    "laravel/framework": "5.6.*",
    "fideloper/proxy": "^4.0",
    ...
  }
}

then do composer update

You will probably break a LOT of things after this

Activity icon

Replied to How To Import From 1 Xls To 2 Tables, Maatwebsites

You can do one of 2 things

  • Supply the id (hardcode it) OR
  • Get the autoincrement id of the first table using this syntax on your first insert then use that for your 2nd insert

https://laravel.com/docs/5.6/queries#inserts

$id = DB::table('tb_user')->insertGetId($insert);
...

Activity icon

Replied to Sending Base46 Via Ajax To Controller

Try base64 ... show code

Jul
29
1 year ago
Activity icon

Replied to Npm Run Prod

Hi, the CDN is a great idea! You are using it like source control but better since it actually serves the assets even more efficiently than on your own server. Thanks man!

Jul
26
1 year ago
Activity icon

Started a new Conversation Npm Run Prod

Hi,

Have a "standard" Laravel app that run npm run prod when I do a release.

So my workflow is

Dev: Macbook running Vagrant, using npm run dev for assets.

  • using gitlab.com private repo for source control

I am using fabric (fabfile.org) to ssh into my PROD server (DigitalOcean Debian 9), do a git pull and rsync into nginx. The last step of fabric is to do a

npm run prod

At this point, it takes about 10 minutes for it to do

npm rebuild node-sass
[..................] - : info using [email protected]
... (about 20 lines of this)
> [email protected] install /var/www/projectname/node_modules/node-sass
> node scripts/install.js

Cached binary found at /home/projectdir/.npm/node-sass/4.7.2/linux-x64-48_binding.node

> [email protected] postinstall /var/www/projectname/node_modules/node-sass
> node scripts/build.js

Binary found at /var/www/projectname/node_modules/node-sass/vendor/linux-x64-48/binding.node
Testing binary
Binary is fine
[email protected] /var/www/projectname/node_modules/node-sass

npm run prod
[..................] - : info using [email protected]
[..................] - : info using [email protected]

> @ prod /var/www/projectname
> npm run production

[..................] - : info using [email protected]
[..................] - : info using [email protected]

> @ production /var/www/harness
> cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js

95% emitting

 DONE  Compiled successfully in 102342ms
...

(output with the asset table)

php artisan view:clear

Question: How do I change my workflow so this does not run on every server every time I release code?

I have tried to pre-compile the node-sass on my Mac but it seems like that is not possible because my servers are running Linux (Debian 9).

So if I have 10 load balanced servers, how do I run this once (somewhere) and have the servers pull them down with the npm run prod so it doesn't take 10 minutes per server to do a push to PROD

Is CI the answer?

Thank you

Nov
16
1 year ago
Activity icon

Replied to Request() Vs $request

Thanks!

Activity icon

Started a new Conversation Request() Vs $request

Hi,

In the 5.5 documentation, the way to get the request is

public function index(Request $request) {
  $value = $request->input('test');
  $input = $request->all();  
}

then there is a helper so this works too

public function index() {
  $value = request('test');
  $input = request()->all();
}

is there a different between the 2? Using the helper request() seems a little bit cleaner but not sure if that going to yield the same results if we make that our coding standard

Aug
30
2 years ago
Activity icon

Started a new Conversation Direct PDO Vs Laravel Config/database.php

Hi,

Trying to connect from a local PHP (running Vagrant with Debian Linux) to an Azure SQL MSSQL.

Installed all the required libs

sudo apt-get install freetds-common freetds-bin unixodbc php php7.0-sybase

then in /etc/freetds/freetds.conf, uncommented tds version = 8.0

Finally got a direct PDO to connect but cannot get it to connect using the config/database.php

This works using PDO directly

$dbh = new \PDO("dblib:host=test1.database.windows.net;dbname=test_db", "username", "password");
$query = $dbh->prepare("SELECT * FROM GroupType");
$query->execute();
$result = $query->fetchAll(); // returns array of records

then using config/database.php does NOT work

...
'testmssqlserver' => [
    'driver' => "sqlsrv",
    'host' => "test1.database.windows.net",
    'port' => 1433,
    'database' => "test_db",
    'username' => "username",
    'charset' => "password",
    'prefix' => '',
],
...
$groupTypes = \DB::connection('testmssqlserver')->select('SELECT * from GroupType');

Error is SQLSTATE[01002] Adaptive Server connection failed (severity 9) (SQL: SELECT * from GroupType)

I have tried using driver = "dblib"

Error is Unsupported driver [dblib]

Next step is to try to trace this down deep into the Laravel database code unless somebody can help.

Thank you very much!

Jan
05
3 years ago
Activity icon

Started a new Conversation Debugbar

After updating to latest debugbar (composer), I am getting this

'ReflectionException' with message 'Class App\Http\Controllers\_debugbarController does not exist' in /var/www/reviv3/vendor/laravel/framework/src/Illuminate/Container/Container.php:741

I have a catch-all route in my routes.php like this

Route::any('/{controller?}/{action?}/{id?}', function ($controller = 'Home', $action = 'index', $id = null) {
    $controller = 'Reviv3\Http\Controllers\\'.ucfirst($controller);
    return App::make("{$controller}Controller")->$action($id);
});

and it seems like it catching it there when it is loading up some of the assets

...
#6 [internal function]: Reviv3\Providers\RouteServiceProvider->{closure}('_debugbar', 'assets', 'jquery.min.map')
...

Not really sure where to figure this out or to debug -- this was not doing this before. Already tried php artisan clear-compile

Jan
02
3 years ago
Activity icon

Replied to Blade Directive Check For Null Before Echo

Hi @mike,

Looks great! Using this, I may be able to add another a 3rd argument "timezone" :)

Thanks, Chris

Dec
31
3 years ago
Activity icon

Started a new Conversation Blade Directive Check For Null Before Echo

Can't seem to figure something simple out in Blade (PHP) for checking null before doing the return

Blade::directive('datetime', function($expression) {
    return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>";
});

When the $expression comes in as null (like a field from a database), the format() throws an error

how can it be something like

Blade::directive('datetime', function($expression) {
    if (empty($expression)) return null; 
    return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>";
});
Dec
17
3 years ago
Activity icon

Replied to Catching HttpExceptions

@devmate perfect, you can do a lot of stuff in this exceptions/handler.php file!

Activity icon

Started a new Conversation Catching HttpExceptions

I am doing a "catch-all" route at the end of my routes.php file per http://stackoverflow.com/questions/29510055/laravel-5-routing

Route::any('/{controller?}/{action?}/{id?}', function ($controller = 'Home', $action = 'index', $id = null) {
    $controller = 'App\Http\Controllers\\'.ucfirst($controller);
    return App::make("{$controller}Controller")->$action($id);
});

So basically, any request that goes all the way down to this last route definition will call and throw a variety of exceptions like Controller doesn't exist, etc.

Is there a way to still catch these and throw a nice abort(404) instead of just showing an exception on the screen?

Thanks, Chris

Dec
16
3 years ago
Activity icon

Replied to Notifications Package (Flash/Session)

@bobbybouwmann had some middleware that was doing this

public function handle($request, Closure $next) 
{
    $response = $next($request);
    /// something
    return $next($request);  // 2nd time
}

so it was processing the request twice.

While I have you on this, do you know the different between

Notification::successInstant("test");

vs

Notification::success("test");  // For redirects??

I could not get the one without the "instant" to work when showing in the view. It seems like it should be the default behavior

// does not work
public function getTest() 
{
     Notification::success("test"); // does not work
    return view(...);
}
Activity icon

Started a new Conversation Notifications Package (Flash/Session)

Hi,

Has anybody used this for L5.x? Following the instructions (seems like for L4/L5)

https://github.com/edvinaskrucas/notification

  • Using composer require edvinaskrucas/notification (installed 5.1.0)

  • Then php artisan vendor:publish --provider="Krucas\Notification\NotificationServiceProvider" --tag="config"

  • Then following the basic Notification::success("Testing"); in a controller method

  • Then @notification() in the view (same results as {!! Notification::showAll() !!})

The notifications seem to be duplicated on the blade views following the basic instructions for the basic container

Probably have to dig into the code to hunt this down :)

It looks like one call is being stuck in the session twice

Activity icon

Replied to Bridging Laravel 4.2 And Laravel 5 Projects Using A Single Domain

This looks like it's going to be a nightmare to maintain if you are talking about ONE subdomain like

http://example.com or http://www.example.com

The best way (obviously) is to separate them into subdomains

http://example.com and http://www.example.com go to the "main" one and then http://legacy.example.com goes to the other Laravel project

then play around with the URL in the links

then refactor the L4 slowly into L5.X

Activity icon

Replied to Storage Folder On Vagrant.

Please specify your OS and Vagrant version.

I've had to do something like below. Basically mount the folder as something else on the config and then at the end redo the permissions

...
Vagrant.configure("2") do |config|
  config.vm.define :www do |www|
    www.vm.synced_folder "/Users/chris/Projects/ProjectName/src/php",
                         "/var/tmp/ProjectName", 
                         type: 'nfs'
   end

  # -- this fixes the 501:dialout user/group mount
  config.bindfs.bind_folder "/var/tmp/ProjectName", "/var/www/ProjectName", perms: "u=rwx:g=rx:o=rwx"
  config.nfs.map_uid = Process.uid
  config.nfs.map_gid = Process.gid

end
Activity icon

Started a new Conversation Using Phery Inside Laravel

Hi,

Wondering if anybody has ever gotten Phery (https://github.com/pheryjs/phery) to work with Laravel. It is sort of between pjax and Vue and may eventually not have a place but familiar with it (from Kohana) so trying to give it a go.

Generally, the way to get this in is composer (PSR-0 only so classes are not namespaced properly \Phery instead of \Phery\Phery) and the next step is to get it into the Controller (request). The goal is to make the controller methods DRY so there is some "before" and "after" stuff that needs to get executed prior to the actually controller method.

It seems like there are a couple of ways to do this

  • Middleware => can be pre or post request - awesome!
    • Probably the cleanest way
    • But loses track of Controller class that contains the method to be executed
    • Can't be global as routes have not fired yet, have to be a routeMiddleware
  • Controller __construct()
    • Doesn't take care of the "after"
  • ServiceProvider
    • Haven't tried this yet
  • Trait
    • Created a trait for the common methods

Roughly the Controller code should be something like if there were the beforeFilter() and afterFilter() which I think are scheduled to be removed in 5.2 in favor of middleware

Some of the issues I have been having

  • How to get the Controller class dynamically from the Middleware
    • \Route::currentRouteAction() returns a closure, not sure how to deal with that (theoretically then list($controller, $method) = explode('@', $currentAction);)
    • $request->route()->getAction() also returns strange
  • Settling on __construct() and after middleware - not sure if this is best
    • In construct, shoving things into $request object instead of member variables for middleware to be able to get to
      • $request->phery = ...
      • $request->pheryConfig = ...
      • $request->pheryResponse = ...
class ExampleController extends Controller
{
    // Member vars
    public $phery;
    public $pheryConfig;
    public $pheryResponse

    // Called every time controller is instantiated
    public function before() 
    {
        if (Phery::is_ajax(true)) {
            $this->pheryConfig = config('phery');
            $this->phery = Phery::instance()->callback([
                'after' => [[__CLASS__, 'cleanupPhery']]
            ]);
            // notice also need __CLASS__ to be the controller that has the trait methods
            $action = request()->input('phery')['remote'];  // from the POST
            // In this example, $action = "functionToCall" 
            $method = 'ajax'.ucfirst($action); // prefix the actual method with ajax
            // $method = "ajaxFunctionToCall" which is the function below
            $this->phery->set([$action => [$this, $method]]); // this is the magic
            // The line above needs the function name and passing $this as the class
            // Can't seem to figure out the Controller class in the middleware
            // Hardcoding a class name results in a static call
            // It should be something like $class = app()->make("NameOfClass");
            $this->pheryResponse = PheryResponse::factory(); // stub a response
        }
    }

    // Actual method to call that has the functionality
    public function ajaxFunctionToCall($data) 
    {
        $this->pheryResponse->alert("test"); // start chaining things to the response
        return $this->pheryResponse;  // return is now handled by the After middleware
    }

    // This is what process the return 
    public function after() 
    {
        if (Phery::is_ajax(true)) {
            $this->phery->config([
                'exit_allowed' => false,
                'return' => true
            ]);
            try {
                if ($this->phery->process() !== false) {  // executes everything
                    $content = $this->pheryResponse->render(); // json 
                }
            } catch (PheryException $exc) {
                \Log::error($exc->getMessage());
                $content = '{"error":"error"}';
             }
            // Intercept the response
            return response($content)->header('Content-Type', 'application/json');
        }
    }

}

Moving to Laravel, currently using BaseController constructor and After middleware. I can't use the member variables so just shoving things into the $request object

Already have the "After" middleware to solve the after() above and shoved all the member variables into the request object being passed around

class PheryAfter
{
    public function handle($request, Closure $next)
    {
        // Perform action
        if (Phery::is_ajax(true)) {
            try {
                if ($request->phery->process() !== false) {
                    $content = $request->pheryResponse->render();
                } else {
                    $content = '{"error":"error in process"}';
                }
            } catch (PheryException $exc) {
                $content = '{"error":"error in exception"}';
            }
            return response($content)->header('Content-Type', 'application/json');
        }
        // If not Phery, keep going
        return $next($request);
    }
}
Dec
08
3 years ago
Activity icon

Replied to Trying To Get Property Of Non-object When Using Eloquent Models

Either a join failed (via lazy or eager loading)

If you dump out the variable using dd(), you should be able to see if the $question->questions is NULL

<?php echo dd($question) ?>   or {{ dd($question) }}

or

<?php echo dd($question->user) ?>

or

<?php echo dd($question->questions) ?>
Dec
07
3 years ago
Activity icon

Replied to Authentication Modification

The RegistersUsers traits is inside the framework itself (not inside the app/ folder) so you shouldn't be touching that.

If you are then thinking about extending the Trait, you probably should create a class http://stackoverflow.com/questions/10056520/extend-traits-with-classes-in-php

You can still use the AuthController (per the example) but remove the use stuff and write the methods inside your class (cut/paste from the trait) and modify as necessary

Thanks, Chris

Activity icon

Replied to Laravel And Lots Of Historical Data

If your data sits in Excel or CSV files or an existing SQL database (MS Access, etc.), just use a SQL database like MariaDB (not MySQL) or Postgres. Then you can use Eloquent.

If your data is in an object database, then you can use the NoSQL stuff. I doubt that anything termed "historic" would be in this format. Eloquent would not do anything for you here.

You don't want to fight your data right off the bat until you get more parts (functionality) of your application worked out

Thanks, Chris

Activity icon

Replied to Entrust : Where Should I Create Roles ?

The ACL in the "out-of-the-box" laravel does not save things to the database, everything is defined in code via a Policy and using the Gate class.

Entrust gives you a bit more control because you can just change the database (no code change/release required).

$subscriber = new Role();
$subscriber->name = 'Subscriber';
$subscriber->save();

goes into a migration in the up() method or you can just manually create these records in the database. Then there is a role_user table where you can match up roles to users. This is course-grained like admin, manager, user, etc. so big chunks suitable for maybe a group route

If you want even more granular stuff (like an extra level), then you can layer in the permissions part. These may be on each of your controller functions but this is not necessary

Dec
05
3 years ago
Activity icon

Replied to Is There Any Third Party Package To To Export Reports As Pdf Which Is Integrated With Laravel ?

I think you meant easy to integrate with Laravel. Anything that uses composer should be easy enough.

There are generally 2 ways to do this

  1. Slow way: you have to lay everything out in code
  1. Convert HTML => PDF (with CSS support)

As long as you can do composer install ..., they should be easy enough to use inside Laravel

Activity icon

Started a new Conversation Using & In Front Of Variables For Return View()

I was used to binding variables to a view (from Kohana) instead of setting them. In Laravel (Blade), you end up getting an exception if you do something like this

Controller
...
public function getIndex() 
{
    return view('folder.index')->with([
        'user' => $user
    ]);
}
...

if $user is not defined

What I have done is something like this (pass by reference)

Controller
...
public function getIndex() 
{
    return view('folder.index')->with([
        'user' => &$user
    ]);
}
...

and it seems to work whether I end up setting the $user or not

Is this a normal pattern?

Thanks, Chris

Dec
03
3 years ago
Activity icon

Started a new Conversation Controller Naming Convention

Has anybody dropped the "Controller" suffix from their naming convention? Seems redundant ... not like we call things UserModel

It's already namespaced inside Http\Controllers

Just tired of seeing all the ***Controller.php in the folders

Dec
02
3 years ago
Activity icon

Replied to Creating A SPA

You can certainly do this with jQuery but that will be fairly painful. You want to use something like Vuejs, React, Mithrill, etc. You will still need some sort of backend right?

The best place to look around and try things out (15 minutes at a time) is here http://todomvc.com/

This will also show you the amount of code vs plain jQuery

Activity icon

Replied to Why $(document).ready(function() Not Work In A Blade View ?

@vincej this is really very basic stuff and not related to Blade at all. Your error is html/css/js (client-side) so make sure you can do that first.

Follow these steps

  • Create a file called test.htm beside your index.php file (in the public folder)
<html>
<head>
   <title>Test HTML Page</title>
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
   <script>
   $(document).ready(function()
   {
     myFunction();
   });
   function myFunction()
   {
      alert("I am an alert box!")
   } 
   </script>
</head>
<body>
TEST HTML PAGE
</body>
</html>

  • Pull this up on your browser, see if it works

  • Once you know what the HTML needs to look like, go back to your Blade template and keep doing a View Source until the HTML is 100% the same

Activity icon

Replied to Why $(document).ready(function() Not Work In A Blade View ?

$ not defined means you do not have jquery loaded BEFORE your document.ready call

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
$( document ).ready(function() {
    console.log( "ready!" );
});
</script>
Activity icon

Replied to Career Advice, Greatful For Any Input.

If you think you have the aptitude, competence AND desire to learn new things (be honest with yourself), the money will always be there.

The reason why the startup may be offering you less money is you are an unknown skill level to them. If you are happy working 40 hours a week and you don't find yourself reading up on new stuff the rest of the time, stick with your old job and at 40 years old you will see younger kids moving ahead of you because this is a "just a job" for you.

If you really want to make a LOT of money in this business (software) and/or survive, you will have to be "working" 60+ hours a week with 20+ of those just reading and learning new things (full stack). 40 hours to get stuff done, the rest of the time just getting better.

Note: when I say reading, I mean actually building something with it, even just doing the tutorials

Activity icon

Replied to Work With A Huge Amount Of Data MySQL

@ElMorin If you are really just a new developer on a new project, then do not worry about the number of rows in MySQL (or MariaDB) -- 1,000,000 records x 100 tables is nothing.

What you want to avoid is n+1 queries which is very easy to stumble into with ORM (Eloquent). If you do one query and return 1,000 records with the proper joins (read up on eager loading), that will be quick even if you are going through 10 other tables. If you return 1,000 records without the proper joins (lazy loading), then you will basically run 1 + 1,000 queries (total of 1,001) which will definitely kill your server.

Activity icon

Replied to Working With Reference Table

@kfirba This is how I have done it in general (still trying to see if this works for Laravel)

Here are my goals:

  • I would like to have what you are saying, a "reference table" with IDs, Names and Codes
  • I would like to have some "hard classes" for my IDE to help me
  • I would like to NOT have to remember all the IDs which are FK'd to the reference table

Here is how I solved these goals:

I have 3 tables for the reference tables (the ... means you can add more as you see fit)

modules (id, name, code, description, rank, ...)
types (id, module_id, name, code, description, rank, ...)
statuses (id, module_id, name, code, description, rank, ...)

So in the modules table, it looks like some sort of listing of the main entity types you have (should also map to some of main table names) so it looks like

0, 'Unknown', 'UNKNOWN', 'Unknown', 0
100, 'User', 'USER', 'User', 100
200, 'Group', 'GROUP', 'Group', 200
300, 'Address', 'ADDRESS', 'Address', 300
400, 'Marital Status', 'MARITAL_STATUS', 'Marital Status', 300

Then in the types table, I would have something like this

0, 0, 'Unknown', 'UNKNOWN', 'Unknown', 0
...
4001, 400,  'Single', 'SINGLE', 'Single', 4001
4002, 400,  'Married', 'MARRIED', 'Married', 4002
4003, 400,  'Divorced', 'DIVORCED', 'Divorced', 4003
4004, 400,  'Widowed', 'WIDOWED', 'Widowed', 4004
...

Then in the profiles table

id, name, marital_status_type_id, ...

I like the way that I am enforcing some sort of sanity into the primary key numbering so that I can quickly figure things out just using the IDs once I see them inside the other tables

So for example, module_id = 400 (Marital Status) has types that are 4001, 4002, 4003 ... You may have to skip numbers as necessary depending on how you anticipate them to grow so that you can have a module 410, then types of 4101, 4102, 4103, etc.

Furthermore, I then have a class that goes to the database and generates a "hard class" for me (similar to https://github.com/barryvdh/laravel-ide-helper). Don't have this working for Laravel yet but hopefully soon. It basically just pumps out code in one file called "lookup.php" (which I include in bootstrap) with a bunch of class definitions that look like this

<?php

// Auto-generated on 12/01/2015 13:45:11, **do NOT touch**

class Module 
{
    const UNKNOWN = 0;
    const USER = 100;
    const GROUP = 200;
    const ADDRESS = 300;
    const MARITAL_STATUS = 400;
}

    public static function getName($id)
    {
        switch($id)
        {
           case 0: return 'Unknown';
           case 100: return 'User';
           case 200: return 'Group';
           case 300: return 'Address';
           case 400: return 'Marital_Status';
        }
    }

   public static function getIdByName($name)
    {
        switch($name)
        {
            case 'Unknown': return 0;
             case 'User': return 100;
             case 'Group': return 200;
             case 'Address': return 300;
             case 'Marital Status': return 400;
        }
    }

    public static function getCode($id) ...
    public static function getIdByCode($code) ...
    public static function getNames() 
   {
        $array = array();
        $array[0] = 'Unknown';
        $array[100] = 'User';
        $array[200] = 'Group';
        $array[300] = 'Address';
        $array[400] = 'Marital Status';
   }
   public static function getCodes() ...
}

// Types

class User_Type
{
    ...
}

class Group_Type
{
   ...
}

class Marital_Status_Types
{
     const UNKNOWN = 0;
     const SINGLE = 4001;
     const MARRIED = 4002;
     ...
     public static function getName($id) ... 
     // Same methods as above, you get the idea
}

Then in my code, I can just use auto-complete for it to give me some constants I can use like so

...
->where(Marital_Status::SINGLE)
...

mouseover on IDE over the constant should give you the actual ID in the database and I don't have to hardcode any of the IDs in the system

My generator code (Kohana version) roughly looks like this

https://gist.github.com/chrisgo/942d2baa22d5871e243d

Activity icon

Started a new Conversation Describe Fields In Models Like Blueprint (Migration/Schema)

Hi,

Is there a way to define Eloquent models more like Blueprint?

In Blueprint (migrations, etc.), you define fields in a more natural fashion which is using the name of the field more of like a "key"

Schema::create('user', function (Blueprint $table) {
            $table->increments('id');
            $table->string('first_name', 50)->index()->nullable();
            $table->string('last_name', 50)->index()->nullable();
            $table->string('email', 100);
            $table->boolean('is_admin');
});

In Eloquent, you define fields "sideways" like using the arrays

...
protected $fillable = ['first_name', 'last_name', 'email'];
//protected $guarded = ['price'];
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
protected $casts = ['is_admin' => 'boolean'];
protected $maps = ['first_name' => 'firstName', 'last_name' => 'lastName'];
...

Maybe this can be defined in Eloquent like so (even bringing in the validation)

...
protected $fields = [    
    'firstName' => [
        'type' => 'string',
        'fillable' => true,
        'map' => 'first_name', // or 'column' => 'first_name',
       'validation' => [
          ...
      ]
   ],
   'lastName' => [
       'type' => 'string',
        'fillable' => true,
        'map' => 'last_name', 
   ],
   'createdAt' => [
       
   ]
   'isAdmin' => [
       'type' => 'boolean',  // cast
        'fillable' => true,
        'map' => 'is_admin', 
   ],
   ...
];
...

Maybe even creating an Field object so that you can do more than just the arrays (inspired by https://github.com/jonathangeiger/kohana-jelly)

...
protected $fields = [
    'firstName' => Eloquent::field('string', [
       'validation' => [[
           'max_length', [':value',500]
        ]],
        'nullable' => true,
        'column' => 'first_name',
   ]),
]
...

or perhaps more Fluent (more like the Schema::create)

$this->addField('firstName', function(Field $field) {
    $field->string('first_name')
            ->validation(...) 
            ->cast(...);
}

This seems better when you are adding fields later in the process so you are basically adding the migration and then adding the field

Thanks, Chris

Nov
30
3 years ago
Activity icon

Replied to Route To Continue Looking

@snapey probably, but looks strange on SEO :(

I am hoping most of the URLs match routes above this (something more specific). I think the code below is expensive because it has to check the file system but oh well

$_page = Request::path();
if (strpos($_page, '/') === false AND view()->exists('content.'.$_page)) {
    Route::get('/{page}',[
        'uses' => 'ContentController@index'
    ])->where('page', '[a-zA-Z0-9_]+');
}
Activity icon

Replied to Route To Continue Looking

@craigchilds94 not quite, I am just trying to not make it match the route if the blade template does not exist. But it seems like it is too late once it goes inside the Route::get(...)

Maybe I can put the if statement outside and wrap it outside the entire route

if (File::exists('resources/views/content/'.$page.'.blade.php')) {
    Route::get('/{page}', function ($page) {
        return App::make("Reviv3\Http\Controllers\ContentController")->index($page);
    })->where('page', '[a-zA-Z0-9_]+');
}
Activity icon

Replied to Route To Continue Looking

Thanks so much guys for the replies!

@Prullenbak: you are right, that looks much better, will change to match yours!

@Snapey: the reason why I want it to keep going is that this is my 2nd to the last route. The last route is the "catch-all" so if the $page doesn't exist, I want it to fall into this one

Route::any('/{controller?}/{action?}/{id?}', function ($controller = 'Home', $action = 'index', $id = null) {
    $controller = 'ProjectName\Http\Controllers\\'.ucfirst($controller);
    return App::make("{$controller}Controller")->$action($id);
});
Activity icon

Started a new Conversation Route To Continue Looking

Is there a way to have Laravel keep going down the list of routes (in the routes.php file) when it is already inside a route?

For example, I have a route that is a "generic" content page like so

Route::get('/{page}', function ($page) {
    return App::make("ProjectName\Http\Controllers\ContentController")->index($page);
})->where('page', '[a-zA-Z0-9_]+');

The controller just does something simple

return view('content.'.$page);

I wanted to see $page exists first before firing the controller ... something like this

Route::get('/{page}', function ($page) {
    if (File::exists('resources/views/content/'.$page.'.blade.php')) {
        return App::make("Reviv3\Http\Controllers\ContentController")->index($page);
    } else {
        return false; 
    }
})->where('page', '[a-zA-Z0-9_]+');

The idea of the return false is to have this route be disregarded (not picked up by laravel) and keep looking for the next route that matches the URL.

Maybe there is a way to rig up the ->where(...) to be a closure?

Oct
09
4 years ago
Activity icon

Replied to Why I Have To Use First() Not Get()

get() will return a collection

Activity icon

Replied to Model Definition

Trying to see if there is a way to define Eloquent models with the "fields" as the starting point.

For example, consider the following table

users

  • first_name
  • last_name
  • is_admin

Currently, you do something like this

protected $map = [
  'firstName' => 'first_name'
  'lastName' => 'last_name'
  'isAdmin' => 'email'
];

protected $casts = [
  'is_admin' => 'boolean',
];
...

which works. When you want to add another field, you have to go through each of these arrays and add the appropriate entry.

If you do it using the fields as the driver, it could look like this

$fields = [
    'firstName' => [
        'cast' => 'string',  // default, can be omitted
        'maxlength' => 100, 
        'column' => 'first_name', 
    ],
    'lastName' => [
        'cast' => 'string',  // default, can be omitted
        'maxlength' => 100, 
        'column' => 'last_name', 
    ],
    'isAdmin' => [
        'cast' => 'boolean',
        'column' => 'is_admin', 
    ],
]

which makes it more intuitive because that is how you add fields to a model and how people think about adding columns to a database ... by defining the field and not by the properties (like $casts, $maps, etc.)

It's not a big deal, I'm just sure I'm not the first one to bring this up and maybe there is something out there that does this already to extend Eloquent.

Oct
08
4 years ago
Activity icon

Started a new Conversation Model Definition

Is there an alternative way to define models where it is more like designing a database? The current way in Eloquent is more orthogonal where each field definition is "sprinkled" across the various array (for example $fillable, $casts, $maps).

Something similar to this where each field of the model is described https://github.com/creatoro/jelly/blob/3.2/master/guide/jelly/getting-started/defining-models.md

So in the course of development, assume you are adding a new field, you have to visit each of these Eloquent protects arrays and make sure you don't miss anything. On the alternative method, you simply add a new definition to the "fields" array and then you are good to go (also saves some introspection)

The example above is from Jelly ORM (used in Kohana) and Phalcon also started out the same way as Eloquent but it added Annotations as an alternative

https://docs.phalconphp.com/en/latest/reference/models-metadata.html (scroll to Annotations strategy)

Maybe there is an extension of something like Ardent or Eloquence? I know these do something different but it seems like its possible to extend Eloquent to do this?

Thanks for any tips!