ORM question - Laravel

Soldato
Joined
13 Jun 2009
Posts
4,236
Location
My own head
Be great if someone can drop me some help here, I understand pretty well the concepts of ORM / Databases / MVC but first time doing boots to the ground as it were.

In Laravel, trying to get my head around relationships, and pushing data into the models, in terms of downstream relationships.

For simple terms, let's say I have

1 x User Model (Contains their id, email, name)
1 x User Data Model (Maybe contains some other attributes i don't want in the main user table)

My User model is using a hasOne with the User Data Model, the User Data Model belongs to User.

Questions at this point:

1. Do I need to manually put the DB fields in the User Data table, for User_ID or should the ORM be doing this for me?

2. I create some data, for example using SEEDS in Laravel

PHP:
        $player = User::create([
            'Name' => 'Olli',
            'Email' => '[email protected]',
        ]);

This works fine, but for adding relating data at the same time, and linking it back to the correct user... Is this completely wrong?

PHP:
      $userid = $user->id;

        UserData::create ([
            'PlayerID' => $userid,
            'attribute1' => '14',
            'attribute2' => '14',
            'attribute3' => '14',
        ]);

My brain is yelling yes, but not 100% sure!

Thanks in advance, I know this is a long one.
 
Be great if someone can drop me some help here, I understand pretty well the concepts of ORM / Databases / MVC but first time doing boots to the ground as it were.

In Laravel, trying to get my head around relationships, and pushing data into the models, in terms of downstream relationships.

For simple terms, let's say I have

1 x User Model (Contains their id, email, name)
1 x User Data Model (Maybe contains some other attributes i don't want in the main user table)

My User model is using a hasOne with the User Data Model, the User Data Model belongs to User.

Questions at this point:

1. Do I need to manually put the DB fields in the User Data table, for User_ID or should the ORM be doing this for me?

2. I create some data, for example using SEEDS in Laravel

PHP:
        $player = User::create([
            'Name' => 'Olli',
            'Email' => '[email protected]',
        ]);

This works fine, but for adding relating data at the same time, and linking it back to the correct user... Is this completely wrong?

PHP:
      $userid = $user->id;

        UserData::create ([
            'PlayerID' => $userid,
            'attribute1' => '14',
            'attribute2' => '14',
            'attribute3' => '14',
        ]);

My brain is yelling yes, but not 100% sure!

Thanks in advance, I know this is a long one.
Are you using migrations?

If you're using numerical incrementing IDs, in your migration file you'll have to include the field for the table with the type integer (obviously varchar if you're using UUIDs). The naming convention for Eloquent is model_id so you would use user_id as the foreign key for your user_data table.

In your User model you would have a hasOne relationship towards the UserData model. If you check the Eloquent documentation, you have a shorthand version which assumes the foreign key will be the name of the model_id or you can manually specify in the relationship which field is the foreign key like so:
PHP:
return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
Then using the $with array you can choose to eager load this relationship in every JSON response.

Your seed data also seems correct with referencing the User model (but I would change the name of the foreign key to match conventions, no camelcase!!)
 
Are you using migrations?

Your seed data also seems correct with referencing the User model (but I would change the name of the foreign key to match conventions, no camelcase!!)

Negative, not using migrations as of yet, but the core tables are setup in migrations no?

In other ORMS, I've seen all fields defined in the model itself... so Laravel seems odd, or I've been doing it completely wrong?

The one I posted there, was indeed seed data, but the problem became even more confusing when I got down to related related models! It's probably completely fudged but this is what I wrote.

PHP:
      $playerIDs = ['12345','1234343345'];

        Model::unguard();
        DB::table('players')->delete();
        DB::table('player_stats')->delete();
        DB::table('matches')->delete();
        DB::table('match_player_data')->delete();
        DB::table('match_kill_data')->delete();

        // Create Players
        $player = Player::create([
            'SteamID' => '12345',
            'Name' => 'Olli',
            'Thumbnail' => '12345',
            'Profile' => 'This is temporary profile filler material. You can write what you want here as long as it does not exceed two hundred and fifty five characters! Hate speech and advertisement will result in a permanent ban from Battle Royale.',
            'Twitch' => '[email protected]',
            'Youtube' => '[email protected]',
            'SteamProfile' => '[email protected]',
        ]);

        $UserData = new PlayerStats(array(
            'Kills' => '14',
            'Deaths' => '10',
            'Wins' => '4',
            'Losses' => '10',
            'TimePlayed' => '14h 35m 12s',
            'WinPoints' => '1452.12',
            'FragPoints' => '1050.25',
            'Type' => '1',
        ));

        $UserData = $player->PlayerStats()->save($UserData);


        $player = Player::create([
            'SteamID' => '1234343345',
            'Name' => 'Rob',
            'Thumbnail' => '12345',
            'Profile' => 'This is temporary profile filler material. You can write what you want here as long as it does not exceed two hundred and fifty five characters! Hate speech and advertisement will result in a permanent ban from Battle Royale.',
            'Twitch' => '[email protected]',
            'Youtube' => '[email protected]',
            'SteamProfile' => '[email protected]',
        ]);

        $UserData = new PlayerStats(array(
            'Kills' => '1',
            'Deaths' => '1',
            'Wins' => '4',
            'Losses' => '1',
            'TimePlayed' => '14h 35m 12s',
            'WinPoints' => '1452.12',
            'FragPoints' => '1050.25',
            'Type' => '2',
        ));

        $UserData = $player->PlayerStats()->save($UserData);

        /*                                                */
        /*                                                */
        /* Create the MATCHES for testing in the database */
        /*                                                */
        /*                                                */
        /*                                                */


        $match = Match::create([
            'uid' => md5(microtime()  . date('MM:DD:YY')),
            'serverIP' => '192.168.0.1',
            'serverName' => 'Cool Server Bro',
            'mapName' => 'Rexehs Map',
            'playerCountStart' => '0',
            'playerCountEnd' => '0',
            'totalKills' => '0',
            'duration' => '46m 38s',
            'type' => '1',
        ]);

        foreach($playerIDs as $pID) {
        print_r($pID);
        $playerID = $pID;

        $player = DB::table('Players')
            ->where('steamid', '=',  $playerID)
            ->first();

        //
        // If user doesn't EXIST, create them and use their instanciation
        // TO DO
        //

        print_r($player);

        //dd($player->SteamID);

        $MatchPlayerData = new MatchPlayerData([
                    'player_id' => $player->id,
                    'placement' => '5',
                    'startWP' => '1500' + rand(0,10),
                    'startRank' => '1600'+ rand(0,10),
                    'endWP' => '1800'+ rand(0,10),
                    'endRank' => '1500'+ rand(0,10),
                    'timeAlive' => '32m 15s',
                    'kills' => '12',
                ]);

        print_r($MatchPlayerData);

        $Matchkilldata = new MatchKillData([
           'player_id' => $player->id,
           'playerLocation' => '292902922',
           'target_id' => '292902922',
           'targetLocation' => '29292922',
           'Weapon' => '292902922',
           'distance' => '292902922',
        ]);

       $match->matchkilldata()->save($Matchkilldata);
       $match->matchplayerdata()->save($MatchPlayerData);

Thanks RE: CamelCase! I will get into the habit of lowercasing everything, it's a habit that stretches from technical writing, to CVs, to coding... it's hard to kick!
 
Negative, not using migrations as of yet, but the core tables are setup in migrations no?

In other ORMS, I've seen all fields defined in the model itself... so Laravel seems odd, or I've been doing it completely wrong?
Are you using the Artisan console at all? You should get into the habit of using migrations as they allow you to roll back changes to your database and make it easy to recreate your application in another environment. The migration file will automatically create the fields with the types you specify and allow you to enable stuff like soft deletion.

The model just defines the fillable fields and relationships, they still need to be created!

The one I posted there, was indeed seed data, but the problem became even more confusing when I got down to related related models! It's probably completely fudged but this is what I wrote.
Just seed the data in the order it's needed.
PHP:
// Create Players
        $player = Player::create([
            'SteamID' => '12345',
            'Name' => 'Olli',
            'Thumbnail' => '12345',
            'Profile' => 'This is temporary profile filler material. You can write what you want here as long as it does not exceed two hundred and fifty five characters! Hate speech and advertisement will result in a permanent ban from Battle Royale.',
            'Twitch' => '[email protected]',
            'Youtube' => '[email protected]',
            'SteamProfile' => '[email protected]',
        ]);

        $userData = PlayerStats::create([
'user_id' => $player->id,
            'Kills' => '14',
            'Deaths' => '10',
            'Wins' => '4',
            'Losses' => '10',
            'TimePlayed' => '14h 35m 12s',
            'WinPoints' => '1452.12',
            'FragPoints' => '1050.25',
            'Type' => '1',
        ]);
It's as simple as that to add a belongsTo relationship.


Thanks RE: CamelCase! I will get into the habit of lowercasing everything, it's a habit that stretches from technical writing, to CVs, to coding... it's hard to kick!
Eloquent isn't strict with naming conventions but it saves you the hassle of even needing to define the table name/keys for the relationships if you stick to the conventions. It's good practice to use camel and snake case where appropriate
 
Eloquent isn't strict with naming conventions but it saves you the hassle of even needing to define the table name/keys for the relationships if you stick to the conventions. It's good practice to use camel and snake case where appropriate

Well an even more fun one, is using the DB::table query, which apparently is case sensitive! On my local worked fine with Player and player, but when on the server, table not found!

I think I've got the hang of it now, seed is great but gone for the full parser now and going great.
 
Well an even more fun one, is using the DB::table query, which apparently is case sensitive! On my local worked fine with Player and player, but when on the server, table not found!

I think I've got the hang of it now, seed is great but gone for the full parser now and going great.
DB::table completely bypasses Eloquent, should be no need to use it unless you're writing really complex queries! Could you share your code?

Use migrations in conjunction with your seeds. Any time you deploy to a new environment you can just run "php artisan migrate" and "php artisan db:seed" to get your DB up to scratch.
 
Back
Top Bottom