Eloquent (WITHOUT Laravel) get data from table with dynamic name - php

I'm sure this is a totally simple question but for the life of me I'm stuck here- we're using Eloquent outside of Laravel due to PHP restrictions. I have a support ticket tracking app that I'm trying to update.
The data structure of this app is such that each ticket is assigned a UUID on submission and a table with that UUID as its name is generated and all changes to the ticket are tracked as new entries in that table.
Following some tutorials on Eloquent I got our models and controllers set up and working but for each one I see that I'm defining the table name in the model itself. IE our ticket model is
namespace Models;
use \Illuminate\Database\Eloquent\Model;
class Ticket extends Model {
protected $table = 'tickets';
protected $fillable = [table columns here];
}
and anything called in the tickets controller correctly and successfully reads and writes data to our tickets table.
So... my question is: how would I go about reading/writing/creating/deleting those previously mentioned UUID tables?
I've tried the built in table selector (ie- DB::table(uuid here) and DB::setTable(uuid here) but to no avail. I get Fatal error: Call to undefined method Models\Database::setTable()
What I'm after is a model/controller that I can reuse for ANY dynamically-named table.

You could create a generic model and dynamically set the table name, like this:
namespace Models;
use \Illuminate\Database\Eloquent\Model;
class FormerUUIDTicket extends Model {
protected $table = 'some_table';
protected $fillable = [table columns here];
}
class SomeController
{
public function someAction()
{
$uuid = $_POST['uuid_field']; //some uuid, the table name
$model = new FormerUUIDTicket;
$model->setTable($uuid);
return $model->get(); //do anything using eloquent with proper table
}
}
Make sure that you always set the table name before use, or it will fail. Don't use static function either, for the same reason.

Related

Is it possible to define a function in the table property of Model Laravel?

Colleagues, help out. I have a list_books_hist(?) function in my database (the database is built on a separate scheme, not tied to migrations) (which we will go to the id and it returns a line from the table of outdated books)
class BooksListHist extends Model
{
protected $connection = 'db_main';
protected $table = 'lst_books_hist(?)'; //--> can I do like this?
}
Then how do I build a query by passing an ID card there? Using AddBinding? How can I work with the BooksListHist model in this case ?
BooksListHist::addBinding("id_book", "select")->select() ? But in this case it doesn't work

Get model table name without query

I have a package media library by spatie. I need to get table name of the model.
I know that I can do this:
public function getPath(Media $media) {
$name = (new $media->model())->getTable()
}
But this creates a new query. I don't need to create an extra query on database. In table media, I have a column a model_type, where records can be like this: App\ModelName. Maybe I can get names of the model without a query?
There is an answer in laravel framework github:
https://github.com/laravel/framework/issues/1436 .
So it seems you will need to extend Media model.
Example from github
class BaseModel extends Eloquent {
public static function getTableName()
{
return with(new static)->getTable();
}
}
class User extends BaseModel {
}
User::getTableName();
I don't think "new model()" created a query on the database, it just spawns a new object instance of the model class. I don't know the library by heart, but given that it's a Spatie library, it probably functions very similar like Eloquent does, which has the same behaviour.

Laravel: passing dynamic table name to model e.g protected $table = "$tablename"

So my code successfully creates dynamic tables of the exact same structure (I need it this way for my own reasons).
However, the problem comes when I want to add data to any of the dynamically created table because I don't have a model for it, the way I have when I normally create tables/models.
So, I was wondering how can I work around this problem?
Can I use this kind of logic somehow?
namespace App;
use Illuminate\Database\Eloquent\Model;
class sys_cats extends Model
{
// I know we can't use variable in class like this
// but this is just to explain what kind of logic I have
// in mind.
$category = Session::get('catName');
protected $table = "$category";
protected $primarykey = 'id';
protected $fillable = [
.
.
.
So I assume, this way, we can use this model to dynamically change table name to the name stored in a session variable.
So we won't have to create a separate model for each of these tables.
Is this achievable? Or I must create a separate model file as well each time when I dynamically create a table in database?
I am sorry, if what I am suggesting is fundamentally wrong or anything related. I am pretty new to PHP and Laravel.
Waiting for your kind suggestions.
Thanks
better to use fluent query builder db
u can add dynamically table name with insert,update,read,delete
operation
for example
get record from db
DB::table($tableName)->all()
for insert
DB::table($tableName)->insert(['name' => $name]);
for automatically added created_at and updated_at add in migration
$table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));

Trouble understanding laravel eloquent models

It's been a some time since I've programmed with Laravel and I'm stumped by the relations I need in order to create a foreign key -link with 2 models.
I have a database where there's a table "company" containing companies, and I also have a table called "projects", which contains projects.
So the Projects- table contains a column called "employercompany" with a foreign key constraint to the company-table.
I'm trying to print out the company's name in a project page in laravel with
{{$project->employercompany->name}}
But keep getting "Trying to get property of non-object"
My model pages look like this:
//Company
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Company extends Model
{
public function projects()
{
return $this->hasMany('App\Projects', 'employercompany', 'id');
}
}
and
// Projects
namespace App;
use Illuminate\Database\Eloquent\Model;
class Projects extends Model
{
public function employercompany()
{
return $this->belongsTo('App\Company');
}
}
I know this is an easy problem but I just can't wrap my head around it
*****EDIT*****
I found the solution. Thanks Radical for providing some insight.
I ended up changing the employercompany column to company_id and, all the others as such too.
After that I fiddled around what I'm guessing fixed the thing was that I changed my database search query from
DB::table('projects')->get();
into
Project::all();
Don't know if that was the change needed but it sure feels like it was.
When defining a belongsTo relation like you have done, Laravel will try and 'guess' the keys you are using based on the class name. In this case, it will look for a column company_id on your Projects model since your model is called Company.
Like you have done for the projects() method on your Company model, you should tell Laravel that you are using the employercompany column to reference the Company model:
public function employercompany()
{
return $this->belongsTo('App\Company', 'employercompany');
}
For more information, see the relevant documentation here.
In addition, to make things easier, it might be worthwhile to try - if possible - to adhere to what Laravel 'expects' your database columns to be called, so situations like this are resolved automatically.
It should be like
$project = Project::find($id); //id of project
$compnany_name = ($project->employercompany()->get())->name;

Calling Correct Database Table with Laravel all()

I am just getting started with Laravel 5. I am trying to set up a basic page that retrieves all data from a database table. I have a table call people and I have a controller called ContactController.php. The controller has the following code:
<?php namespace App\Http\Controllers;
use App\Contact;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ContactController extends Controller {
public function index()
{
$people = Contact::all();
return $people;
}
}
When I access my page, I get the following error:
QueryException in /home/vagrant/sites/laravel/vendor/laravel/framework/src/Illuminate/Database/Connection.php line 614:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'homestead.contacts' doesn't exist (SQL: select * from `contacts`)
Why is it trying to access homestead.contacts? My table is called people. I never created a table called contacts. Where is it drawing the table name from and how do I correct this?
Thanks.
Quote from the docs:
Note that we did not tell Eloquent which table to use for our User model. The lower-case, plural name of the class will be used as the table name unless another name is explicitly specified.
So if you define nothing else, Laravel will take the plural snake_case version of your class name:
Contact => contacts
FooBar => foo_bars
To fix your issue either change the model name accordingly. In this case Person will let Laravel search for the table people.
Or explicitly specify the table in your model:
class Contact extends Eloquent {
protected $table = 'people';
}
Do you have the right table name in your app/Contact.php model?
protected $table = 'people';
Or are you using the wrong model?
Add the following line to your Contact model (app/Contact.php).
protected $table = 'people';
This will work.

Categories