In laravel eloquent relationship, is it still necessary to make migration even though there's an existing database? beginners here.
I create a one-to-one eloquent relationship inside my model to get the specific column from another table's record and fetch to the datatable, but it did not work.
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Directorystatus extends Model
{
use HasFactory;
protected $table = 'user_status';
protected $fillable = ['status_id' , 'status_xtitle'];
public function userbasic() {
return $this->belongsTo(directorybasic::class,'user_xusern','status_xuser');
}
}
class Directoryuser extends Model
{
use HasFactory;
protected $table = 'user_basic';
protected $primaryKey = 'user_id';
protected $fillable = ['user_id' , 'user_xusern' , 'user_xfirtname' ,'user_xmiddlename','user_xlastname'];
public function userstatus() {
return $this->hasOne(directorystatus::class,'user_xusern','status_xuser');
}
}
No. Migrations are not necessary. Defining relationships on both sides is also not necessary, if you don't need them both. (You can have only belongsTo, without having hasOne or hasMany in the opposite model.)
First, make sure you are using the right object (Directorystatus::class / Directoryuser:class - I see they're not capitalized in your code). The next param is the foreign key, meaning the column which points to a model's primary key. The third param is optional and is used only if the primary key is not id.
For example if you have a column status_xuser in the table user_status, which contains a user_id from user_basic table, you should define it like this:
public function userbasic() {
return $this->belongsTo(Directoryuser::class,'status_xuser','user_id');
}
And in order to use this relationship, when you retrieve a model from the db, for example, you should call on it the same way your relationship function is named.
$status = Directorystatus::find(1);
$user = $status->userbasic();
I would also suggest you name your classes in camelCase, because it's the accepted practice (in Laravel especially).
Related
I have a table with three primary keys, I'm trying to create a model for it, and I'd like to use the find () function, but it throws the error:
Code:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Visit extends Model
{
protected $table = 'ft_visit';
protected $primaryKey = ['sk_time', 'sk_region', 'sk_device'];
protected $fillable = [
'sk_time', 'sk_region', 'sk_device', 'ds_page',
];
public $timestamps = false;
public function time()
{
return $this->belongsTo(Time::class, 'sk_time');
}
}
Error:
(1/1) ErrorException
mb_strpos() expects parameter 1 to be string, array given
You can try the solution presented in this article Solved: Eloquent doesn’t support composite primary keys.
Adding the setKeysForSaveQuery method below on your model, and removing the $primaryKey attribute, you might be able to add this otherwise not supported functionality to your Eloquent model.
<?php
use Illuminate\Database\Eloquent\Builder;
class Visit extends Model {
public $incrementing = false;
protected function setKeysForSaveQuery(Builder $query)
{
$query
->where('sk_time', '=', $this->getAttribute('sk_time'))
->where('sk_region', '=', $this->getAttribute('sk_region'));
->where('sk_device', '=', $this->getAttribute('sk_device'));
return $query;
}
}
EDIT: As noted by #Devon this might affect Eloquent in other ways and should be tested thoroughly before use. However, this should give you some clearance on the way to solve it, should you not be in a position where you can (preferably) restructure the application or data.
Eloquent does not support composite keys. The best thing to do in this scenario to ensure Eloquent compatibility is to convert your existing primary composite key to a unique composite key and add an autoincrement primary key (id) for Eloquent to use.
Unfortunately you can't. Laravel and lumen (using Eloquent) do not support composite keys.
I need to filter the active clients from a route using Eloquent.
I'm working with a third party database that I can't modify. In my project I have two models: Cliente(client) and Ruta(route), which have a many to many relationship, so I added the belongsToMany relationship in my models.
The only column I'm interested from the pivot table is called DESACTIV, which tells me if a Client is deactivated for a Route.
Ruta model:
class Ruta extends Model
{
protected $connection = 'mysql2';
protected $table = 'truta';
protected $primaryKey = 'CODIRUTA';
public function clientes(){
return $this->belongsToMany(Cliente::class, 'tcpcarut', 'CODIRUTA', 'CODICLIE')->withPivot('DESACTIV');
}
}
Cliente model:
class Cliente extends Model
{
protected $connection = 'mysql2';
protected $table = 'tcpca';
protected $primaryKey = 'CODICLIE';
public function rutas(){
return $this->belongsToMany(Ruta::class, 'tcpcarut', 'CODICLIE', 'CODIRUTA')->withPivot('DESACTIV');
}
}
What I need is to get the active (or non deactivated) Clients given a specific Route.
I have done it on my controller like this:
$miRuta = Ruta::where('CODIRUTA','=',$ruta)->first();
$clientes = array();
foreach ($miRuta->clientes as $cliente){
if ($cliente->DESACTIV == 0){
array_push($clientes, $cliente->NOMBCLIE);
echo end($clientes)."<br/>";
}
}
And it works fine, but I don't think it's elegant. I know this can be archieved through Eloquent, I'm just to noob at it and don't know how to do it.
Maybe I could add the filter on the clientes method on my Ruta model, so it would return only the active Clients.
Or maybe It could be best to add a method on the Cliente model, like isDeactivated
I know it sounds like I know what I'm talking about but I need someone to hold my hand on this, I'm just too noob with Eloquent :/. Examples would be much appreciated.
You can use the wherePivot method to constrain a relationship based on values in the pivot table. You just need to add the following to your Ruta model
public function desactivClientes() {
return $this->clientes()->wherePivot('DESACTIV', 0);
}
And then you just have to modify the rest of your code a bit to use the constrained relationship. I'm also adding a null check because if this function does return null, which can happen if your table doesn't have a record where CODIRUTA matches whatever is in $ruta, then it will likely throw a fatal error trying to call a method on a non-object.
$miRuta = Ruta::where('CODIRUTA','=',$ruta)->first();
$clientes = array();
if ($miRuta !== null) {
$clientes = $miRuta->desactivClientes()->pluck('NOMBCLIE');
}
I am modelling a report which depending on its type (missing person, wanted, etc) could contain different fields but each type shares a number of fields. This I think is what differentiates this question from say: this question where the fields are common across all types.
At the moment I have created a report model with an integer field indicating its type which references a type table. The advantage is that this is an easy model to understand and implement. It means that I can also easily search for objects. On the other hand, this means that some fields do not make sense for some models and thus are always null. As I add fields unique to the individual types I end up with many columns in the table of which many are null.
I would like some advice on using Laravel's (5.2) polymorphic relationships. The way I envision this is that I will have a base report model that contains all the shared fields and have the MorphTo fields; then have the different types separate containing their unique fields in a one-to-one relationship with the reports model. Is this possible and does this even make sense? The problems I see are that I lose the ability to search across all "reports" regardless of type. Or is there a way around this like say Java where inheritance allows for sub-classes to be considered members of the superclass?
A rough diagram of such relationships is shown below. Reports holds the shared fields while Wanted and Missing have unique fields.
From the diagram representing the relations in your question above, I think it is a straight forward case of parent - child.
Here, your BaseReport or Report is the parent model so to say and the WantedReport and MissingReport are the child - so to say.
Only thing which needs to be changed in your diagram is that you need to define the foreign key of report_id in your child tables to point to the parent record in the base reports table.
Table-reports
id // primary key
date
description
Table - wanted_reports
id //primary key
report_id //foreign key linking to the reports table
status_at
is_captured //maybe a boolean field
charge
Table - missing_reports
id //primary key
report_id //foreign key linking to the reports table
status_at
is_found
last_seen_date
last_seen_at
The you can define the corresponding models as - Report
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Report extends Model
{
protected $table = 'reports';
protected $fillable = ['report_date', 'description'];
public function wanted_reports()
{
return $this->hasMany(WantedReport::class);
}
public function missing_reports()
{
return $this->hasMany(MissingReport::class);
}
}
WantedReport
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class WantedReport extends Model
{
protected $table = 'wanted_reports';
protected $fillable = ['report_id', 'status_at', 'is_captured', 'charge'];
public function report()
{
return $this->belongsTo(Report::class);
}
}
MissingReport
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class MissingReport extends Model
{
protected $table = 'missing_reports';
protected $fillable = ['report_id', 'status_at', 'is_found', 'last_seen_date', 'last_seen_at];
public function report()
{
return $this->belongsTo(Report::class);
}
}
Then anywhere in your application you can access the relations like you normally do, for example
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ReportsController
{
public function store(Request $$request)
{
$report = $this->model->create([
'report_date' => Carbon:::now(),
'description' => $request->get('description')
]);
if($report)
{
$wantedReport = $report->wanted_reports()->create([
'status_at' => $request->get('status'),
...
]);
$missingReport = $report->missing_reports()->create([
'status_at' => $request->get('status'),
...
]);
}
}
}
Hope this helps
I have a model named "User". I want "Password" field from Eloquent from another table, and when user calls the user::all() method, all selected fields from different tables come in the result.
How can i do that?
Results are not displayed in with() .
my problem solved by using $appends in Eloquent model .
my code :
class User extends Eloquent {
protected $table = 'user';
protected $attributes = ['password'];
protected $appends = ['password'];
public function getPasswordAttribute()
{
return $this->getPAsswordMethod();
}
}
Your question is extremely board and borderline unanswerable but I will give you a board solution.
You are able to establish relationships to other tables via the Model objects you create. Lets pretend you have a Password table which belongs to the User.
User model:
public function password()
{
return $this->hasOne(Password::class, 'FK', 'PK');
}
You can now do User::with('password')->get(['FieldName']); and this will give you all of the passwords which have the above relationship to a user.
I have been able to set up a m:m relationship in eloquent outside laravel and retrieve records but I have no idea how to add a new record as you dont create the pivot table in the code.
If these are my classes, how would i add a new instance to the M:M relationship between author and publisher?
<?php
include 'eloquent_database.php';
class Publisher extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'publisher';
protected $primaryKey = 'publisher_id';
public function authors (){
return $this->belongsToMany('Author', 'author_publisher', 'publisher_id', 'author_id');
}
}
class Book extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'book';
protected $primaryKey = 'book_id';
public function author() {
//related table name, pk in current table,
return $this->belongsTo('Author', 'author_id');
}
}
// Create the company model
class Author extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'author';
protected $primaryKey = 'author_id';
public function books()
{
//related table, fk IN related table,
return $this->hasMany('Book', 'author_id');
}
public function publishers (){
return $this->belongsToMany('Publisher', 'author_publisher', 'author_id', 'publisher_id');
}
}
I would also need to know how to delete one too. I have seen this documentation http://laravel.com/docs/4.2/eloquent#working-with-pivot-tables but i dont really follow it
Id really appreicate an exxample of how to add and delete a new instance. Also onine there seeems to be so many different versions its hard to find which docs to follow as the code i have works but i didnt get it from the docs - just trial and error
Thanks a lot in advance
edit:
in repsonse to Rays comment i do have a pivot table in the database called author_publisher with author id and publisher id but i have no idea how to work with this pivot table. Do i have to create a class for it? I dont really understand
Here is a reference to said table in the code above
return $this->belongsToMany('Author', 'author_publisher', 'publisher_id', 'author_id');
When having a M:M relationship, make sure you have a table that translates the relationship between author and publisher. An example table could be composed of entries including both author_id and publisher_id. From what you have provided, you lack such a table.
There's another case if you do not have such a table. In order for such a M:M relationship to work, the author table must contain a column called "publisher_id" for simplicity. Likewise the publisher table must contain a column called "author_id". Then in the author model, return $this->hasMany('Publisher', 'author_id') and in the publisher model, return $this->hasMany('Author', 'publisher_id'). You should get the correct answer.