Create database schema and eloquent - laravel

I have a doubt about eloquent, it should be a very basic doubt but Im not understanding.
For example, if we build a db diagram in mysql workbench or something like that, then if we want to create the same shema in laravel we need to add in the migrations the necessary id´s right?
The eloquent relationships (hasMany, belongsTo, etc) are just methods to fetch the info that is necessary in some context but the database schema, the relationships are set with the ids in the migrations right? The relationships (hasMany, belongsTo, etc) are not mandatory to build the database schema?

The migration would define the foreign keys that form the relationships described by hasMany, belongsTo, etc.
A seeder would need to do as you suggest and get the id for the row in the associated table so it can be populated in the foreign key column.
You can, of course, do some seeding in your migrations, but that should be done under very clear and limited circumstance.

Related

Laravel Dynamic Eager Loading for Dynamic Relationships

Laravel Version: 5.5
PHP Version: 7+
Database Driver & Version: mysql 5.7+
Scenario:
I have a SaaS application that has flexible database structure, so its fields are bound to change, especially given it has a Json field (for any extra database structure to be created from client side of the application), including relationship based fields. so Account Table can have dynamically created employee_id field, and thus the need to access relationships dynamically
Problem:
I need to EagerLoad models based on this dynamic relationship. If I had something like this:
// Account Model
public function employee(){
return $this->belongsTo(App\Employee);
}
it would be easy. But what I have is this:
public function modelBelongsTo(){
return $this->belongsTo($dynamicClassName, $dynamicForeignKey);
}
Now if I eager load this, I'll get Account Model instance with related Employee on key modelBelongsTo. This is how Eloquent Names based on the function of eagerload. But after this I cannot use this function again to eagerload a second model because it'll just overwrite results on modelBelongsTo key.
Possible Solution Directions:
1) Can I Somehow change laravel's process to use a name I provide?
or
2) Can I write functions on the fly to overcome this so I'll write employee function on the fly?
or
3) Worst Case Scenario: I iterate over all records to rename their keys individually because I am using a pagination, it wouldn't that big of a deal to loop over 10 records.
Us a morph relationship
define the various dynamic classnames say
Employee
Boss
Morph works by having the related key and the table name stored in the parent table, it means to relate them you have to use a join or an orm and you cant have foreign key constraint on it as it links to different tables.
then have your account have morphs where
we have
Account
as top class
then we have
EmployeeAccount, BossAccount
which have their relation to boss and employee
then in Account have morphto relation call it specificAccount()
to which in its child morphs have the morph relation to Account
then add it to $with so to eager load them so when fetching account you could simply do
$account ->specificAccount
to get its morph child. which is nullable
This is totally dynamic such that if you have other classes in future you can just add and add the morph relationship. This may be applied to any reflection or runtime evaluated and loaded classes/code though it is not advisable to do this, as you can always edit code to create new functionality without affecting previous.

using laravel migrations to access tables already created

I have some tables that are already created in the database. The migrations seem to require that you first destroy the table and then create it. From what I understand, the creation process generates a "model" at the same time as well as "getters" and "setters" for the fields.
The problem is that I have a database full of tables already. I would like to access the tables that have already been created using Laravel as an interface. Is there a way to generate a model, getters and setters for tables that already exist?
How can I best do this?
TIA
The default model generator doesn't create any getters or setters. All it does is create a basic model class with the correct model name based on the table name. You can create the models without actually creating the migration. The command is php artisan make:model ModelName.
So the answer to your question is no, there isn't any. You need to manually create each model and add the methods yourself. You might try your luck with some laravel package which might do this for you.
Note : Laravel Eloquent is an ActiveRecord implementation. You don't need any getters or setters to work with the table columns. Even a completely empty model with the correct name to match the table would be enough to start using Eloquent.

How to create models for dynamically generated tables (on the fly)?

I stumbled upon this problem today. My project has a few tables, for which I have created their dedicated Models. However, my project allows user to create dynamic tables.
How do I create relationships or models for/between these dynamically generated tables?
I would not recommend to create Eloquent Models on dynamically generated tables, because Eloquent Models are here to help developers with already created database tables (features like relationships, scopes, attributes casting are usually defined for existing database tables).
What would be my recommendation? Use the Query Builder instead. You will have almost the same functionalities of Eloquent Models, except without model.
Instead of having something like:
DynTable::where('foo', 123)
->where('bar', 456)
->first();
You will have the following:
DB::table('dyn_table')
->where('foo', 123)
->where('bar', 456)
->first();
Basically, the same. But, with the benefit that you can specify any table name to the Query Builder, but you can't change the table name to an Eloquent Model (in a running script).

Laravel5: How are Eloquent model relationships expressed in the database?

There's a missing link I fail to understand.
I use migrations to create database tables and I define the relationships there. meaning.. if I have a person table and a job table and I need a one to many relationship between the person and jobs, I'd have the job table contain a "person_id".
When I seed data or add it in my app, I do all the work of adding the records setting the *_id = values etc.
but somehow I feel Laravel has a better way of doing this.
if I define that one to many relationship with the oneToMany Laravel Eloquent suports:
in my Person model.....
public function jobs()
{
return $this->hasMany('Jobs);
}
what's done on the database level? how do I create the migration for such table? Is Laravel automagically doing the "expected" thing here? like looking for a Jobs table, and having a "person_id" there?
Yep, Laravel is doing what you guess in your last paragraph.
From the Laravel documentation for Eloquent Relationships (with the relevant paragraph in bold):
For example, a User model might have one Phone. We can define this
relation in Eloquent:
class User extends Model {
public function phone()
{
return $this->hasOne('App\Phone');
}
}
The first argument passed to the hasOne method is the name of the
related model. Once the relationship is defined, we may retrieve it
using Eloquent's dynamic properties:
$phone = User::find(1)->phone;
The SQL performed by this statement
will be as follows:
select * from users where id = 1
select * from phones where user_id = 1
Take note that Eloquent assumes the foreign key of the relationship based on the model name. In this case, Phone model is assumed to use a user_id foreign key.
Also note that you don't actually have to explicitly set the foreign key indexes in your database (just having those "foreign key" columns with the same data type as the parent key columns is enough for Laravel to accept the relationship), although you should probably have those indexes for the sake of database integrity.
There is indeed support to create foreign key relationships inside migration blueprints and it's very simple too.
Here is a simple example migration where we define a jobs table that has a user_id column that references the id column on users table.
Schema::create('jobs', function($table)
{
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
});
You can also use some other methods that laravel provides such as onDelete() or onUpdate
Of course to understand better the options that are available to you please read the documentation here.
Edit:
Keep in mind that Eloquent is just using fluent SQL wrapper and behind the scenes there are just raw sql queries, nothing magical is happening, fluent just makes your life a lot easier and helpers you write maintainable code.
Take a look here about the Query Builder and how it works and also, as #Martin Charchar stated , here about Eloquent and relationships.

Dynamically set the table name in a "has many" relation model

In my database schema, I have multiple tables that hold generic data for objects, for instance I have a user table and a user_data, post table and post_data, and so. these *_data tables all hold a foreign key to the object and a pair of key-value. now in my laravel models I would like to have a single data models for these tables (rather than a model for every single one) and represent the has_many relation in a dynamic way where somehow I can define the table name according to the parent model. I think the parent model would have something like:
return $this->hasMany('data');
but I don't know how to express the inverse relation nor how to tell laravel which *_data table to use. so my question is, is it possible? and if so, how?
You have two options.
Either create a model for each data_* table and use the relation as stated with $this->hasMany('data'); and $this->belongsTo('User'); in the data table and the user table.
Or you can use Polymorphic relations, I personally prefer the polymorphic relations solution, more neat.

Resources