Laravel 4 many to many relationship does not display the related data - many-to-many

I'm working with the following models: Game, User and Player where Player extends User. In this case Game and Player have a relationship of N:N and User extends Confide. So code stands like:
app/models/Game.php
<?php
class Game extends Eloquent {
protected $guarded = array();
protected $table = 'users';
public $timestamps = false;
public function players(){
return $this->belongsToMany('Player');
}
}
app/models/User.php
<?php
use Zizaco\Confide\ConfideUser;
class User extends ConfideUser {
protected $table = 'users';
public $timestamps = false;
protected $hidden = array('password');
//Here go original Confide functions
}
app/models/Player.php
<?php
class Player extends User{
public function games(){
return $this->belongsToMany('Game');
}
}
I've populated the pivot table called game_player. As player extends user, pivot table is like this:
game_player
id
game_id
user_id
But if I run this super simple example I have an error:
$game = Game::find($gameId);
$player = $game->players(); //Error in this line
Error
Call to undefined method Illuminate\Database\Query\Builder::players()
I'm confused because I'm not having the error about pivot table was not found so I could think relationship is created fine.
On the other hand if I var_dump games var I obtain:
var_dump($game)
object(Game)[181]
protected 'table' => string 'games' (length=5)
//more var info about DB
protected 'relations' =>
array (size=0)
empty
protected 'hidden' =>
array (size=0)
empty
protected 'visible' =>
array (size=0)
empty
protected 'guarded' =>
If relationship would be created fine... shouldn't relations var have any data?
Thanks!

Just pointing out somethings that could solve the problem:
Your Game.php has the wrong table name.
When you get players, the line should be:
$game = Game::with('players')->find($gameId);
$player = $game->players;

Related

Laravel Sql query groupBy and Order

I need some help to make a query.
Database tabless
Example:
The user inserts a actor name(name and surname) and i need to loop over all the movies and then retrieve which category has more occurrences.
I need some help to make the query(this one is only a sketch):
$src=array("Leonardo","DiCaprio");
$film2=film::with('category')->with('actor')->wherehas('actor', function($q) use($src){
$q->where('first_name', $src[0])->where('last_name', $src[1]);
})->wherehas('category', function($qr){
$qr->groupBy('name')->orderBy('name', 'DESC');
})->FIRST();
model Film:
class film extends Model{
protected $table = "film";
protected $primaryKey = 'film_id';
public $timestamps = false;
use HasFactory;
protected $sql=['film_id', 'title', 'length'];
public function category(){
return $this->belongsToMany(category::class,'film_category', 'film_id', 'category_id');
}
public function actor(){
return $this->belongsToMany(actor::class,'film_actor', 'film_id', 'actor_id');
}
}
model Actor:
class actor extends Model{
protected $primaryKey = 'actor_id';
public $timestamps = false;
use HasFactory;
protected $sql=['actor_id', 'first_name', 'last_name'];
}
model Category:
class category extends Model{
protected $table = "category";
protected $primaryKey = 'category_id';
public $timestamps = false;
use HasFactory;
protected $sql=['category_id','name'];
public function film(){
return $this->belongsToMany(film::class,'film_category', 'category_id', 'film_id');
}
}
Here is the solution:
In Actor.php add Join
public function filmActor(){
return $this->hasMany(FilmActor::class, 'actor_id','actor_id');
}
Find the actor with filmActor join table
$src=array("Leonardo","DiCaprio");
$actor=Actor::whereHas('filmActor')->where(['first_name' => $src[0],'last_name'=> $src[1]])->first();
Put film_id in the array
foreach($actor->filmActor as $film){
$filmIds[]=$film->film_id;
}
Get FilmCategory who have filmIds
$filmCategory=FilmCategory::whereIn('film_id',$filmIds)->get();
Put category_id in the array
foreach($filmCategory as $category){
$categoryIds[]=$category->category_id;
}
Count how much is duplicate category_id
$count =array_count_values($categoryIds);
Get the higher counted $max = max($count);
Get the key of max which is category_id $key = array_search($max, $count);
Here is the category who has more occurrences.
$category=Category::where('category_id',$key)->first();

Can I use two tables on CodeIgniter's model?

I want do receive data from my table "users" and to insert other data into the table "olders", however I only know how to access it from this:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Eixoxy_model extends CI_Model {
protected $table = 'users';
protected $table_id = 'id';
public function __construct() {
parent::__construct();
}
public function getMarketing(){
$mkt = $this->db->get_where('users', array('area' => 'marketing'));
return ( $mkt->num_rows() > 0 ) ? $mkt->result_array() : false;
}
This is what I'd like to insert on other table:
$this->Eixoxy_model->create($xy);
$xy = $this->input->post(); //I want to somehow insert $xy into table "olders"
It is possible to add another table simply by including:
protected $table2 = 'test';

Laravel Eloquent Getting children of children via model relqtionships

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

Chainings multi-to-one relations in Laravel

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

How to display attributes from an object using my_controller in codeigniter

I want to be able to display attributes from a table anywhere in my application and have them be edited by the user. This means the data will come from a row in a database. Each column has a default value which can be changed by the user if they so choose.
The table columns may look like this:
| id | admin_id | practitioner | practitioners | student | students | and so on ...
Here is my model:
class Lang_trans_model extends CI_Model {
public function get_lang_trans($admin_id){
$this->db->where('admin_id', $admin_id);
$query = $this->db->get('lang_trans');
return $query->row();
}
Here is my MY_Controller:
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('key_items_model');
$this->load->model('lang_trans_model');
foreach ($this->key_items_model->get_key_items() as $result){
$this->label[$result->key] = $result->value;
}
//$admin_id = $this->session->userdata('admin_id');
$admin_id = 3;
$lang = $this->lang_trans_model->get_lang_trans($admin_id);
//not sure what should go here????
//I want to be able to use $lang->practitioner; to be able to have practitioner, or the edited attribute to show on the page
var_dump($lang);
// produces the following:
//object(stdClass)[26]
//public 'id' => string '3' (length=1)
//public 'admin_id' => string '3' (length=1)
//public 'practitioner' => string 'blah' (length=4)
//public 'practitioners' => string 'blahplural' (length=10)
How do I finish the MY_Controller to be able to use these data fields anywhere in my application?
I do not mind using object oriented syntax or array syntax. Whichever is easier. I just can not figure out how to display the fields without using a foreach statement in every view. I want to call the data with the $lang->practitioner; format in the view.
Thanks in advance.
Declare parent class properties. Than call it from child class:
class MY_Controller extends CI_Controller
{
public $lang;//parent variable declared
public function __construct()
{
parent::__construct();
$this->load->model('key_items_model');
$this->load->model('lang_trans_model');
foreach ($this->key_items_model->get_key_items() as $result) {
$this->label[$result->key] = $result->value;
}
//$admin_id = $this->session->userdata('admin_id');
$admin_id = 3;
//dedicating value to variable
$this->lang = $this->lang_trans_model->get_lang_trans($admin_id);
}
}
Child controller:
class Practitioners extends MY_Controller
{
public function __construct()
{
parent::__construct();
// no need to call model if it is called in parent controller
}
public function index()
{
var_dump($this->lang);
}
}