I'm creating an app using laravel. Tables and columns will be created on the frontend applying the schema codes inside the controller. But how can I do to create models without programming each one manually? Any idea to code it?
Controller example (is working fine):
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class teste extends Controller
{
public function CreateTable(Request $tableName)
{
Schema::create($tableName, function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
//return view
}
}
You can use this to create models from your controller.
Artisan::call('make:model ' + $modelPath + '/' + $request->modelName)
Now there are a lot of options to create migrations, controller, resource routes etc. along with the model. You can check them out if you want.
The command will create the model. You can create the model from the table name of course. But it will not follow the naming conventions. Like table names are in plural and model name are in singular form with the first letter in upper case.
If you had used artisan to create the table migration along with model Laravel would've handled some complex namings. Like Category model with categories table, or Software model with software table. That's why I recommend sending the model name separately from your view.
The real problem arises when you plan to build a whole model programmatically along with the fields. Laravel does not allow you to do that. You would have to build a custom command to handle this.
Also, even if you make the fields programmatically, you'd still have to go back to the model to define the relations. You can build your custom command to handle this too.
However, you can go through this question to have some idea. This guy asked for a similar thing like you.
Also, there are some packages that read your table and backtrack it to build your model. Here's an example. Another example here.
Note: if you plan on building your custom command and make it open-source please let me know.
Related
Coming from a long Symfony-Doctrine background, I have started learning Laravel 8.
One of my first discovery was that migration needed to be manually created after using make:migration (from what I understood thus far) in both Models and Migration.
Symfony, with Doctrine, allowed a bunch of automatisation, and I only needed to create the field or relation from the Model (php annotation or yaml) - before launching doctrine:schema:validate and make:migration
https://symfony.com/doc/current/doctrine.html#migrations-adding-more-fields.
Let 'say I create a Post and Comment entity, with a One-To-Many relationship.
If I define the relation in the php classes
class Comment extends Model
{
/**
* Get the Post owning this comment
*/
public function post()
{
return $this->belongsTo(Post::class);
}
}
Post class
class Post extends Model
{
/**
* Get the comments for the blog post.
*/
public function comments()
{
return $this->hasMany(Comment::class);
}
}
Is possible to generate the migration scripts that would update the database and create these relation ship ? Or will I have to rewrite it twice (once in the PHP class with hasMany/BelongsTo then again in the Migtration file ?
Not having a central file to map/read a model (which linkied php and database) seems weird to me now.
I've only started but the documentation does not seems to mention anything equivalent
Edit : for more clarity : I'm asking if there are equivalent of Generating migration code/script from models (or a central mapping file : yaml or annotation ) without having to write fields to both migration and models ( in $fillable or other fields...)
Edit 2 Closest thing I could find is this
https://github.com/laracasts/Laravel-5-Generators-Extended
Another use case where this is cumbersome : many-to-many migrations
Having to manually write that third middle table from scratch is really something I wish was made automatically.
In laravel framework despite other famous fameworks like symfony or python django, you're responsible for making database migration files. By this way, you are free to customize your database schema and add any database constrains like (unique constrain, relation constrains and etc.). Also you can add any raw sql using \DB::unprepared(); in your migration files.
I can tell you that it is normal to be a little confuse about this flow, because you've used to this kind of automation in other frameworks like I did, but beilieve me, you get to used to this flow.
By the way, there are some packages out there that do this automation (create migration files according to model) for you.
For creating a migration you need to run command
php artisan make:migration migration_name
And for creating a model you need to run command
php artisan make:model table_name
Refer to this link
https://laravel.com/docs/8.x/eloquent#generating-model-classes
By creating a model you create a table, where you can define the columns types and different properties and define the relationship with other tables.
By creating a migration file you can define the table columns and the constraints.
Background:
I am having my first encounter with any MVC framework, as I am developing a little application with PHP web framework Laravel v6 and MongoDB (with jenssegers moloquent) as database engine. I am following this tutorial series to learn Laravel 6.
Normally when I used to develop such applications with simple php, I would create one file called readFromDb.php and in it I would find/read/select data from all DB tables (collections in Mongodb). Then I would include in on top of every PHP file in which I would need to do some processing on any data from DB.
For example, if I have the following collections
allPaintingsCollection
paintingHistoriesCollection
paintingCategoriesCollection
artGalleriesCollection
paintingArtistsCollection
supervisorArtistsCollection
smPlatformsCollection
nonSmPlatformsCollection
targetSchoolsCollection
I would select all records/documents from them into associative arrays in the readFromDb.php, and then include readFromDb.php on top of every page where I would need to display or do processing on data from DB.
Question:
Now, in Laravel, should I create such a script called readFromDb.php and include it on top of every function in every single controller? In that case, where should I put this readFromDb.php file, and how do I include it in controllers?
Or should I write code to read from relevant DB collection/table in each function in every controller, before using that data from DB?
I am using class and call it as repository to handle all my request through database
First i create an file UserRepository
<?php
namespace App\Repositories;
use App\Model\User;
class UserRepository
{
function getUsers(){
Return User::get();
}
}
Then in Controller, you just need to call the repository in the parent of contruct
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
protected $user;
function __construct(){
$this->user = new UserRepository();
}
function index(){
$users = $this->user->getUser(); // getUser() is the function inside the repository class
return view('user',compact('users'));
}
}
That's how I do code in laravel, because i dont want to call Laravel Model and do all the store, reads inside Controller and cause messy code
Laravel has Eloquent ORM what presents Object Relation Mapping interface.
In Introduction:
The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table. Models allow you to query for data in your tables, as well as insert new records into the table.
Basically, same as your readFromDb.php file but it handles with OOP so codebase is very understandable and expandable and strictly related with your code.
When querying with Eloquent you use Models. If your query result has single row you get single Model, if your result has multiple rows you get Eloquent\Collection result set contain your models.
Finally, you mustn't write ORM in Laravel because you already have.
If you think high level abstract accessors; you should explore design patterns. After that you can think to Repository Pattern, Decorator Pattern etc.
Hi so i have a project that is already done but there was a request to add a new column to a specific table i was thinking of a way to add that new column to my table without using migrate or php artisan method to it. i was thinking if it is posible to implement it in the controller. say for example the column name is isOut then values should be false not null. thanks for any advice
You can use the Schema Builder inside a controller as well as in migrations.
Just include use Illuminate\Support\Facades\Schema;
Then run this inside a controller function:
Schema::table('table_name', function($table)
{
$table->boolean('isOut')->default(false);
});
Take care only to run the controller function once, for example by creating a special route to this function with a random string.
you know that using gii tool we can generate models and view controllers, so, the question is :
Is it possible to generate a model without using the gii tool, I mean, just doing it through the php code like calling some method giving required parameters to it and so on?
If you want to create a model called company, create a file named Company.php in models folder and add the following
namespace app\models;
use yii\db\ActiveRecord;
class Company extends ActiveRecord {
// add your functions and properties here
}
N.B. : This is for the latest version of Yii, ie Yii 2.0
I am using CI2.0 with PHP 5.3
I just started to use “Datamapper ORM” and it is excellent!! however their is a one big problem regarding the classes’ names
I have a database table called “users” so my dm model is “user” and also I have a controller with the same name “user”?
so using the “user” model within the “user” controller is imposible!!
what is the best way to solve this problem?
Many Thanks
best regards
One of the drawbacks in CodeIgniter is that you cannot name a controller, model or library the same thing. This is mainly a PHP issue as obviously you cannot name anything the same, but it can be avoided in two ways.
PHP Namespaces - no can do, they are PHP 5.3 only and 90% of the community would kick off if they were implemented.
Controller Prefixes - This is something I would love to add, but... well it would break stuff for everyone. We'll have to wait until 2.1 at least for a change that big.
For now all I can recommend is you name your models and libraries carefully.
Controller - Users
Library - User
Model - User_model | User_m
It's annoying, but just one of those things for now.
so using the “user” model within the
“user” controller is imposible!!
Umm no it isn't, you need to check the UserGuide more carefully ;)
http://codeigniter.com/user_guide/general/models.html#loading
You may give your model a name other than what it is orginaly defined as:
If you would like your model assigned
to a different object name you can
specify it via the second parameter of
the loading function:
$this->load->model('Model_name', 'fubar');
$this->fubar->function();
All you need to do is change your controller file name and class name to "Users". You don't need to change your model name.
controller: users
model: user
db table: users
Take a look at the Datamapper docs.
I would suggest :
Controller - Users or/and User
Library - Users_lib or Users_library or User_lib or User_library
Model - Users_model or Users_m or User_model or User_m
Keep the words User and Users for the controller so you keep nice url.
Just be consistent with the use of plural or singular for the model and controller.
I named in case of 'Project' like that:
Controller:
Project extends MY_Controller extends CI_Controller
Model:
ProjectModel extends Model
In View
project/projectManager // as main content
project/_projectItem // with _ underscore as subView
That works fine at all.
The way I handle it is to end all my controller name's with _controller.
I use datamapper as well so I had a lot of name collisions. For users I have a User (model) and a User_Controller.
Then i simply add:
$route['user'] = 'user_controller';
to the config/routes.php file and voila.
Only downside of this is that if you have a large project with a lot of pages (like me) you end up with a huge routes.php file especially if you have a lot of functions that have a lot of parameters, the routing can become quite a pain in the ass.