Is there any possible way to generate database from models in Laravel? - laravel

Is there any possible way to generate database from models in Laravel ?
I am working on an existing laravel project,it contains models without their migrations.
I tried the reliese/laravel also the doctrine but nothing won't work ..any help ?

Suppose you have model Userwithout migration then you can get table name from it like
User::getTableName(); there is same function to get column names and you can get column types from protected $cast = []
Here is Sample code
$location = new LocationTable(); // load your model
$tableName = $location->getTable(); // this will give a table name from your model
$columnsWithType = $location->getCasts(); // set all your table fields as cast
Schema::create(tableName , function (Blueprint $table) use ($columnsWithType) {
foreach ($columnsWithType as $columnName => $type) {
$table->$type($columnName);
}
});

Related

One to Many relationship in Laravel Eloquent giving undefine method

I am having the said problem when defining one to many relationship with two models, the Student and Enrollment. When accessing the table from another table using:
$enrollment = App\Enrollment::first();
$enrollment->students()->first_name;
Im getting :
Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'students.enrollment_id' in 'where clause' (SQL: select * from `students` where `students`.`enrollment_id` = 1 and `students`.`enrollment_id` is not null)'
However when I use :
$enrollment = App\Enrollment::first();
$enrollment->students()->first_name;
Im getting :
PHP error: Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$first_name on line 1
Can someone help me on this?
Enrollment
protected $fillable = [
'subject_code',
'subject_description',
'section',
'schedule',
'room_no',
'no_of_units'
];
public function students()
{
return $this->hasMany('App\Student');
}
Student
protected $fillable = [
'enrollments_id',
'student_no',
'first_name',
'last_name',
'middle_name',
'birthdate',
'fathers_name',
'mothers_name',
'phone_no',
'degree_id',
'city_id',
'address'
];
public function enrollment()
{
return $this->belongsTo('App\Enrollment');
}
Here's the table for the students and enrollment accordingly
Schema::create('students', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('enrollments_id')->unsigned();
$table->integer('student_no');
$table->foreign('enrollments_id')->references('id')->on('enrollments')->unsigned();
$table->string('first_name');
$table->string('last_name');
$table->string('middle_name');
$table->date('birthdate');
$table->string('fathers_name');
$table->string('mothers_name');
$table->string('phone_no');
$table->string('address');
$table->integer('city_id');
$table->integer('degree_id');
$table->timestamps();
});
Schema::create('enrollments', function (Blueprint $table) {
$table->increments('id');
$table->string('subject_description');
$table->string('subject_code');
$table->time('schedule');
$table->string('room_no');
$table->integer('no_of_units');
$table->string('section');
$table->timestamps();
});
First of all what you exactly want
as per your question i am assuming you want 'enrollment has many students', for this relationship you need enrolment_id in students table not student_id in enrollment table.
and after that use
$students= Enrolment::find(id)->students;
it will return all students with the required enrollment id
That normal since you're trying to get property first_name from hasMany object, you should use get() method if you want to get Collection of objects (in your case collection of students) :
$enrollment->students()->get();
And if you want to get the first name you should specify the object you want to get the first_name from it, e.g :
$enrollment->students()->first()->first_name;
$enrollment->students()->last()->first_name;
If you want to get the attribute first_name of all the students you should use lists method, e.g :
$enrollment->students()->lists('first_name');
Output: collection of all students first names.
Hope this helps.
Update :
Try to remove ->unsigned() in :
$table->increments('id')->unsigned();
and also in :
$table->foreign('enrollments_id')->references('id')->on('enrollments')->unsigned();
When you call relations on an eloquent object it actually return you the relation not the exact objects
for eg: in your case
$enrollment->students() will return the relation
where as
$enrollment->students will return the eloquent object ( in belongs to, has one relations ) and collection/array of eloquent object/objects(in one to many , many to many relations )
simply if you are using it as an attribute you will get the actual result and relation query if it is called as a function
even if you get the relation you can get the results by calling get on top of that
$enrollment->students()->get()

One model to several tables Laravel 5

I have MySQL database tables, of which names are in "yyyymmdd" format. I need to select several tables, for example, from "20150901" to "20150930". I think there might be a way to implement only one model for those tables.
If somebody knows how to do so, please help.
Thanks.
immagine that this is your model.
class XYZ extends Eloquent {
public function __construct($table, array $attributes = array()){
parent::__construct($attributes);
$this->table = $table;
}
}
and you have 7 tables suppose for 1 week.
then inside controller loop you can have like
$reportData = array();
foreach($tables as $table) {
$xyzObj = new XYZ($table);
$reportData[] = $xyzObj->get();
//add your query stuff here like where and fetching records
}

Eloquent MorphMany relationship proxy attribute

In my application I made the strange observation, that a seemingly equal operation has different results to another.
I have the following tables:
aliases:
$table->engine = "InnoDB";
$table->increments("id");
$table->morphs("aliasable");
$table->string("alias");
$table->string("locale");
categories:
$table->engine = "InnoDB";
$table->increments('id');
The Category model has a relationship to the Alias model:
public function aliases()
{
return $this->morphMany("Alias", "aliasable");
}
When trying to manipulate the data of the alias of a category there is a difference between the two following methods:
$category = Category::find(1);
$alias = $category->aliases()->first();
$alias->alias = "test";
$alias->save();
$category = Category::find(1);
$alias = $category->aliases()->first()->alias = "test";
$category->aliases()->first()->save();
The first one is working, the second one is not saving the change.
I would like to get the second version working as I try to implement a proxy attribute on my Category model in order to change the alias like so:
$category = Category::find(1);
$category->germanAlias = "Heidi";
$category->push();
Do you have any idea why my way is not working as expected?
The key thing to understand here is the way relationships are cached on the model. When you access the relationship method directly, then no caching occurs. You are basically instantiating a new Query based off of that relationships definition.
$query = $category->aliases();
$alias = $query->first();
If you access the relationship as if it were a member/attribute of the model, then it will load and cache the relationship as a collection on the model.
$collection = $category->aliases;
$alias = $collection->first();
Future attempts to access the related model by this method will reference the same cached collection of models. This should work.
$category->aliases->first()->alias = 'test';
$category->aliases->first()->save();
Within /Illuminate/Database/Eloquent/Model __get() is a magic method that redirects request for undefined members to the getAttribute() method. The code comments do a pretty good job of explaining the rest but basically it checks for, loads, caches and reuses the relationships.
$category->aliases()->first()->save();
This line select first alias and saves it. Doesnt actually do anything. Your first method is correct. You could also do
$category->aliases()->first()->update(['alias' => 'test']);
if your alias field is included in the $fillable property of the Alias model
EDIT
Run the code below and compare the object ids;
$alias = $category->aliases()->first()->alias = "test";
var_dump(alias);
dd($category->aliases()->first());

Using find() in Laravel to retrieve a database object

I am working through the Laravel 4 From Scratch tutorial at https://laracasts.com/series/laravel-from-scratch. Tutorial 4: Database Access describes several methods for retrieving data from a database.
One in particular I cannot get to work:
In my routes.php, I have
Route::get('/', function()
{
$bottle = DB::table('bottle')->find(1);
dd($bottle);
});
The only output is the "Whoops, looks like something went wrong." page. In the bottle table of my database, the primary key has the name bottle_ID. I would guess this has something to do with the problem, but I cannot find any information on how to change the find() parameter. So how do I use 'find' to return an object from my database?
The following code does work:
// returns everything from bottle table
$bottles = DB::table('brewery')->get();
return $bottles;
// returns all data for the bottle with an ID of 10
$bottle = DB::table('bottle')->where('bottle_ID', '=', 10)->get();
return $bottle;
// returns all ales from the database
$bottles = DB::table('bottle')->where('beer_type', '=', 'Ale')->get();
return $bottles;
When used in the query builder (DB::table()...) the find() method has the primary key column hardcoded as id:
public function find($id, $columns = array('*'))
{
return $this->where('id', '=', $id)->first($columns);
}
What you should do instead is use where() and first():
$bottle = DB::table('bottle')->where('bottle_ID', 1)->first();
Or if you decide to use Eloquent Models you can specify the key column name:
class Bottle extends Eloquent {
protected $primaryKey = 'bottle_ID';
}
And retrieve the model like this:
$bottle = Bottle::find(1);

Many-to-Many and Eager loading query

I am new with Laravel, I was able to query Many-to-Many relationships. Where 'template_dynamic' is the pivot of two tables 'template' and 'dynamic'.
// Template Model
class Template extends Eloquent
{
protected $table = 'template';
protected $guarded = array('template_id');
protected $primaryKey = 'template_id';
public function dynamic()
{
return $this->belongsToMany('dynamic', 'template_dynamic')
->select('*')
->withPivot('template_dynamic_id')
->orderBy('template_dynamic_html_sort', 'ASC');
}
here I was able to retrieve the records
// Template Controller
$dynamic_fields = Template::find($rec->template_id)->dynamic;
what I want to do now is that pivot table has-many properties 'template_dynamic_option'. How will I query the records and combine it with $dynamic_fields variable?
// What I want to do is something like this. But sadly this is an invalid syntax
$dynamic_fields = $dynamic_fields->with('template_dynamic_option');
Any recommendation or enhancements are welcome.
Thank you in advance.
First, I am pretty sure you don't need the select('*') in your relationship query there.
But let's get to your actual problem ;)
To access the pivot table in Eloquent is pretty simple.
$dynamic_fields = Template::find($rec->template_id)->dynamic;
foreach($dynamic_fields as $dynamic){
var_dump($dynamic->pivot)
}
The thing is though, by default only the keys of the pivot table are present in the object.
To change that you have to define them with withPivot(). Actually like you already did but not with the id.
public function dynamic()
{
return $this->belongsToMany('dynamic', 'template_dynamic')
->withPivot('template_dynamic_option')
->orderBy('template_dynamic_html_sort', 'ASC');
}
And if you have multiple additional columns use this syntax:
->withPivot('template_dynamic_option', 'foo', 'bar');

Resources