I'm trying to directly edit my Kodi MySQL DB and build a tool to fix some scraping errors that have always been not quite right.
the relationship of tables is
tvshow -> episode -> file
So I'm able to so far (after creating models for these tables)
List all shows
view specific show and list all episodes
show file entry for that episode.
What I'm trying to do is list all files that belong to the show, via a dropdown. ( as I need to change them )
So I need to use the TVShow model to get all epiodoes that have an idShow entry.. AND then get all the files based on the episode table. I know that Eloquent can handle this typically, but I've only ever used my own table structure, never one like this.. so I think my issue is over riding key names etc...
the key column names are:
idShow
idEpisode
idFile
(Where that SAME name is used as the primary key on the parent table AND the mapping ID in the child table)
Anyhoo, here's my models..
Any ideas?
TVShow
<?php
namespace App\Models;
use Eloquent as Model;
class TvShow extends Model
{
public $table = 'tvshow';
protected $primaryKey = 'idShow';
public function episodes()
{
return $this->hasMany(Episode::class, 'idShow');
}
}
Episode
<?php
namespace App\Models;
use Eloquent as Model;
class Episode extends Model
{
public $table = 'episode';
protected $primaryKey = 'idEpisode';
public function tvshow()
{
return $this->belongsTo(TvShow::class, 'idShow', 'idShow');
}
public function season()
{
return $this->hasOne(Season::class, 'idShow', 'idShow')->where('season', '>=', 0)->where('idSeason', $this->idSeason);
}
public function file()
{
return $this->hasOne(File::class, 'idFile', 'idFile');
}
public function files()
{
return $this->hasMany(File::class, 'idFile', 'idShow');
}
}
File
<?php
namespace App\Models;
use Eloquent as Model;
class File extends Model
{
public $table = 'files';
protected $primaryKey = 'idFile';
public function episode()
{
return $this->belongsTo(Episode::class, 'idFile', 'idFile');
}
}
I'm calling this in my Controller...
TvShow::with('episodes.files')->get();
I'm getting ALL shows as a list..?
A hasManyThrough relationship will work. Add this to your TvShow model.
public function files()
{
return $this->hasManyThrough(Episode::class, File::class);
}
See https://laravel.com/docs/7.x/eloquent-relationships#has-many-through
Related
I have table relation like this:
Is it possible to get the data of the project from the cash mutation table?
In example in cash mutation table with id '4' I wanna call agency name from projects table.
I've done it with with (eager loading in Laravel) but it returns null like:
$cash_mutations = CashMutation::where('id', 4)->with('project')->get();
This is my CashMutation Model:
class CashMutation extends Model
{
use HasFactory;
protected $guarded = ['id'];
public function category(){
return $this->belongsTo(Category::class);
}
public function balanceType(){
return $this->belongsTo(BalanceType::class);
}
public function project(){
return $this->belongsTo(Project::class, 'cash_mutation_id', 'id');
}
public function deposit(){
return $this->hasMany(Deposit::class);
}
}
and this is my Project Model:
class Project extends Model
{
use HasFactory;
protected $guarded = ['id'];
public function cashMutation(){
return $this->belongsTo(CashMutation::class);
}
public function projectFunding(){
return $this->hasMany(ProjectFunding::class);
}
public function SharingProfit(){
return $this->hasMany(SharingProfit::class);
}
}
Is it possible to do that in Laravel? If it possible anyone want to tell me about it? Thanks
Yes. It is definitely possible.
You don’t get an error message so the basic configuration should be fine.
I suspect that the data in the database is not correct. What’s the project_id for the CashMutation with the id 4? Is it maybe null?
This is my first time to try out Eager loading.
Here is my controller code.
I add 'WITH' into my code but I got this error
Call to undefined method Illuminate\Database\MySqlConnection::with()
I've been searching how to put WITH. but I've got error always. Could you teach me right code please?
class ProductController extends Controller
{
public function index(){
$products = Product::with(All());
$products = DB::with('products')
->join('creators', 'creators.id', '=', 'products.creator_id')
->join('categoris', 'categoris.id', '=', 'products.categori_id')
->join('branches', 'branches.id', '=', 'products.br_id')
->join('users', 'users.id', '=', 'products.user_id')
->get();
$data = array(
'title' => 'index',
'no' => 1,
'products' => $products,
);
return view('product.index',$data);
}
Update
Product
class Product extends Model
{
protected $fillable = ['title','kansu','creator_id', 'br_id','user_id' ,'categori_id'];
public function index()
{
return $this->belongsTo('Categori');
}
}
Categori
namespace App;
use Illuminate\Database\Eloquent\Model;
class Categori extends Model
{
protected $fillable = ['pr_name'];
public function index()
{
return $this->belongsTo('Product');
}
}
UPDATE
the with eager loading is used with Laravel Eloquent.which means you first need define model like Product model here,and you need define relation between models like belongsTo hasMany.
for example
we had define two models Product and Category
we define the relation,Product belongsTo Category
then we can call Product::with('category') with eager loading
the DB:: method is only used in laravel database for lower level database operation,there is no model concept at DB:: method,you can directly use DB:: to construct the raw sql you want
the example of relation define
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = ['title','kansu','creator_id', 'br_id','user_id' ,'categori_id'];
public function categor(){
return $this->belongsTo(Categori::class);
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Categori extends Model
{
protected $fillable = ['pr_name'];
public function products(){
return $this->hasMany(Product::class,'categor_id');
}
}
be aware of the foreign key and local key
Eloquent determines the foreign key of the relationship based on the parent model name. In this case, the Phone model is automatically assumed to have a user_id foreign key. If you wish to override this convention, you may pass a second argument to the hasOne method
you can read the laravel relation document
Hi I am having problems with relation and database design.
There are three tables called 'articles' , 'users' , and 'companies' with one attribute each called id:
"articles" -id
"users" -id
"companies" -id
The article table contain many publishers that are user model or company model.
My pivot table must be something similar to 'authors' -id, -model_id, -model_name, -article_id
Is there any way to get article's publisher ids and data from models in one collection with a single query? Maybe I misunderstood the problem and there is a simpler solution for that case.
thx in advance
Assuming Article only have one company or one user , The right way to do that is to do a one to many (polymorphic) relationship creating the table with these columns:-
{ article_id , articleable_id , articleable_type }
and then define it in your model
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
/**
* Get all of the owning articleable models.
*/
public function articleable()
{
return $this->morphTo();
}
}
and the Users table:-
class Userextends Model
{
/**
* Get all of the user's articles.
*/
public function articles()
{
return $this->morphMany('App\Article', 'articleable');
}
}
and same in the Company model:-
class Company extends Model
{
/**
* Get all of the companies articles.
*/
public function articles()
{
return $this->morphMany('App\Article', 'articleable');
}
}
and then you can retrieve the relationship using:-
$user = App\User::find(1);
foreach ($user->articles as $article) {
// do this
}
as mentioned here
but if the article can have more than user or company then you have to do many to many polymorphic as mentioned here
#Mohamed Gabr
the problem is that i need this in many to many way.
and i don't have problem to receive article from User model or Company.
I need receive authors from Article.
i assume there will be something like that.
class Article extends Model
{
public function authors()
{
return $this->hasMany('App\Article_Authors','article_id');
}
}
class Article_Authors extends Model
{
public function authorable()
{
return $this->morphTo();
}
public function article(){
return $this->belongsTo('App\Article');
}
}
class User extends Model
{
public function authors()
{
return $this->morphMany('App\Article', 'authorable');
}
}
class Company extends Model
{
public function authors()
{
return $this->morphMany('App\Article', 'authorable');
}
}
i can make it work but i don't think its good practice
I implement this models
class Article extends Model
{
public function authors()
{
return $this->hasMany('App\Article_Authors','article_id');
}
}
class Article_Authors extends Model
{
public function authorable()
{
return $this->morphTo();
}
public function article(){
return $this->belongsTo('App\Article');
}
}
class User extends Model
{
public function authors()
{
return $this->morphMany('App\Article', 'authorable');
}
}
class Company extends Model
{
public function authors()
{
return $this->morphMany('App\Article', 'authorable');
}
}
and after call $article->authors i get
0
id 1
record_id 2
authorable_id 1
authorable_type "App\\User"
created_at "2019-03-22 15:56:38"
updated_at "2019-03-22 15:56:38"
1
id 2
record_id 2
authorable_id 1
authorable_type "App\\Company"
created_at "2019-03-22 15:56:59"
updated_at "2019-03-22 15:56:59"
how to call this models now :(
#MohamedGabr
Edit :
after making research i didn't find any option to get result in one query there is only option to make a loop and checking instants of model.
its generate a loot loops for collection i need cache result and please settle for this temporarily.
thx For help
i would like to provide data from the "foreign key table" in the current model.
I am currently achieving this by a function (getBrand).
But now I would like to have this accessable as a property. So I added a property ($brand) and wanted to fill it by calling the function (getBrand) in the constructor of the model.
class Car extends Eloquent {
public $brand;
public function __construct() {
parent::__construct();
$this->brand = getBrand();
}
public function getBrand() {
return $this->belongsTo('App\Brand', 'FK_BrandId')->first()->Brandname;
}
}
But this creates an error during the execution of the constructor:
Trying to get property of non-object
Any ideas how to solve this? Thanks!
You could change your getBrand function a little to the following to define the relationship between a Car and a Brand:
public function brand() {
return $this->belongsTo('App\Brand', 'FK_BrandId');
}
The brand model can then be accessed from an instance of Car with, e.g. $car->brand. To access the brand name you can then use $car->brand->Brandname.
If you'd like to access the brand name directly, you could define an "accessor" on the Car model like this:
public function getBrandNameAttribute()
{
return $this->brand->BrandName;
}
You would then be able to access the brand name with $car->brand_name.
I have 3 models: User, Query, Offer. The relation is that user has many queries and query has many offers.
In controller I use $queries=User->query()->get(); (query() is a hasMany method in User model) and pass it to view as parameter. In view I want to display a table of queries from single user and count all offer made to each query.
Actually what I want to get, is a nested object $queries like
user:
query1:
offer1
offer2
query2:
offer3
offer4
How it should be coupled in models and how to use it in controller and view?
You could have something like:
Class User extends Model{
protected $table = 'users';
public function query(){
return $this->hasMany('App\Query');
}
}
Class Query extends Model{
protected $table = 'queries';
public function offer(){
return $this->hasMany('App\Offer');
}
public function user(){
return $this->belongsto('App\User');
}
}
Class Offer extends Model{
protected $table = 'offers';
public function query(){
return $this->belongsTo('App\Query');
}
}
Then in your controller you can have something like this:
public function showUser($id){
$user = User::with('query.offer')->find($id);
return View::make('user')->with('user', $user);
}
Then in your view you could have something like:
#foreach($user->query as $query)
{{$query->title}}
#foreach($query->offer as $offer)
{{$offer->title}}
{{$offer->amount}}
#endforeach
#endforeach