Laravel 5.5 relation Many to many - php

I'm doing my first project with laravel 5.5 aç and now I'm establishing models and relationships
My project consists of a social network of video games.
The two models that I want to relate are the following, it would be a many-to-many relationship:
the genre of the game:
class Genero extends Model
{
protected $primaryKey = "cod";
public $incrementing = true;
protected $keyType = "int";
protected $table = "generos";
protected $fillable = ["cod","nombre"];
//public $timestamps = false;
public function juegos(){
return $this->belongsToMany('App\Juego',"juegosGeneros","codGenero","codJuego");
}
}
And the Game
class Juego extends Model
{
protected $primaryKey = "codJuego";
public $incrementing = false;
protected $keyType = "int";
protected $table = "juegos";
protected $fillable = ["cod", "nombre"];
//public $timestamps = false;
public function generos(){
return $this->belongsToMany('App\Genero',"juegosGeneros","codJuego","codGenero");
}
}
My db tables are that:
CREATE TABLE juegos(
cod INT AUTO_INCREMENT,
nombre VARCHAR(50),
PRIMARY KEY (cod)
);
CREATE TABLE generos(
cod INT AUTO_INCREMENT,
nombre VARCHAR(50),
PRIMARY KEY (cod)
);
CREATE TABLE juegosGeneros(
codJuego INT,
codGenero INT
);
My problem:
I have inserted data in the tables and when retrieving them
<?php
$juego = \App\Juego::where("cod","1")->first();
dd($juego->generos);
?>
they returned me an empty array
Collection {#188 ▼
#items: []
}
Observing the queries made to the database laravel do this:
select `generos`.*, `juegosGeneros`.`codJuego` as `pivot_codJuego`, `juegosGeneros`.`codGenero` as `pivot_codGenero`
from `generos`
inner join `juegosGeneros`
on `generos`.`cod` = `juegosGeneros`.`codGenero` where `juegosGeneros`.`codJuego` is null
Idont know the reason of this condition, and I think that is the problem
where `juegosGeneros`.`codJuego` is null
I really appreciate your help

You set the wrong primary key:
class Juego extends Model
{
protected $primaryKey = "cod";
}

Related

Create one to many table relationship with text input Laravel

I have two tables with a one to many relationship - gratitude_journal_entries and self_gratitudes. Multiple self gratitudes (which are submitted as text entries by the user) can apply to 1 gratitude_journal_entry. The data is passed to these two tables via a form.
I am trying to store the self gratitude text entries in an array and then pass these to the self_gratitude table along with the foreign key from the gratitude_journal_entries table.
The problem I'm having is I'm not sure how to take the input from the array and store this in the self_gratitude column.
Here are the columns for the gratitude_journal_entries table
Here are the columns for the self_gratitudes table
Here are the models and the store method in my controller
class SelfGratitudes extends Model
{
protected $table = 'self_gratitudes';
public $primarykey = 'id';
public function gratitudeJournalEntries() {
return $this->belongsTo(GratitudeJournalEntry::class);
}
}
class GratitudeJournalEntry extends Model
{
protected $table = 'gratitude_journal_entries';
public $primarykey = 'id';
public $timestamps = true;
public function user() {
return $this->belongsTo('App\User');
}
public function selfGratitudes()
{
return $this->hasMany(SelfGratitudes::class);
}
public function store(Request $request)
{
$this->validate($request, [
]);
$gj_entry = new GratitudeJournalEntry;
$gj_entry->user_id = auth()->user()->id;
$gj_entry['entry_date'] = date('Y-m-d H:i');
$self_gratitudes = $request->has('self_gratitudes') ? $request->get('self_gratitudes') : [];
$tj_entry->save();
$gj_entry->selfGratitudes()->sync($self_gratitudes);
return redirect('/dashboard')->with('success', 'You submitted a new journal entry');
}
If you want to keep array in database you can use casting on your columns:
laravel document
class SelfGratitudes extends Model
{
protected $casts = [
'self_graitude' => 'array',
];
protected $table = 'self_gratitudes';
public $primarykey = 'id';
public function gratitudeJournalEntries() {
return $this->belongsTo(GratitudeJournalEntry::class);
}
}

Laravel Multiple linking column in another table with relationships?

I'm trying to create a league table in Laravel but I'm running into some issues with guess what, relationships, again. They never seem to work for me in Laravel. It's like they hate me.
I have a modal for matches
<?php
namespace App\Database;
use Illuminate\Database\Eloquent\Model;
class Match extends Model
{
protected $primaryKey = 'id';
protected $table = 'matches';
public $timestamps = false;
protected $guarded = ['id'];
}
And a modal for teams, but with a matches() function
<?php
namespace App\Database;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
protected $primaryKey = 'id';
protected $table = 'teams';
public $timestamps = false;
protected $guarded = ['id'];
public function matches() {
return $this->hasMany('App\Database\Match', 'team_one_id, team_two_id');
}
}
I think the issue comes with team_one_id, team_two_id as the teams primary key could be in either one of them columns for the other table. When calling count() on matches() it throws an error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'matches.team_one_id, team_two_id' in 'where clause' (SQL: select count(*) as aggregate from matches where matches.team_one_id, team_two_id = 1 and matches.team_one_id, team_two_id is not null)
can you try this syntax
return $this->hasMany('modelPath', 'foreign_key', 'local_key');
Does Match table have a column maned 'team_id'?
because it's the default naming convention in the laravel docs for mapping the tables.
if you do have the column and populate the data you can just remove the foreign & local keys from matches() relationship. you don't need it. Laravel will automatically map it for you.
if you do not have the 'team_id' on Matches table please add the column and add the respective team ids for matches.
<?php
namespace App\Database;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
protected $primaryKey = 'id';
protected $table = 'teams';
public $timestamps = false;
protected $guarded = ['id'];
public function matches() {
return $this->hasMany('App\Database\Match');
}
}
This way you can implement it, Add these relationship and a method in Team Model
public function homeMatches() {
return $this->hasMany('App\Database\Match', 'team_one_id');
}
public function awayMatches() {
return $this->hasMany('App\Database\Match', 'team_two_id');
}
public function matches() {
return $this->homeMatches->merge($this->awayMatches);
}
Now Fetch the data
$team = Team::find(1);
$matches = $team->matches(); //now it will fetch all matches for both columns
If you want to fetch matches as attributes then you can add one method
in your Team model
public function getMatchesAttribute()
{
return $this->homeMatches->merge($this->awayMatches);
}
Now you can fetch the matches as $matches = $team->matches;
Here is the difference
$team->matches returns Illuminate\Database\Eloquent\Collection
And
$team->matches() returns Illuminate\Database\Eloquent\Relations\{Relation Name}
You can't use matches in Eager loading like Team::with('matches') because matches is not a relationship and that causing your Error. What you can do is add homeMatches and awayMatches in eager loading and then call $team->matches().
$teams = Team::with('homeMatches', 'awayMatches')->get();
$teams->each(function ($team) {
print_r($team);
print_r($team->matches());
});

Eloquent create says column has no default value using Laravel 5

I have an small API that i want to save into client mysql database.
For this purpose i'm using guzzle.
my controller:
public function index()
{
$http = new \GuzzleHttp\Client;
$res = $http->request('GET', 'http://localhost:8080/api/address');
$addresses = json_decode($res->getBody(),true);
// dd($addresses);
Address::create($addresses);
}
my model:
class Address extends Model
{
protected $primaryKey = 'Adresse';
protected $fillable = ['Adresse', 'Mandant', 'Kategorie', 'Matchcode', 'Name1'];
public $timestamps = false;
}
my migration:
public function up()
{
Schema::create('addresses', function (Blueprint $table) {
$table->integer('Adresse')->primary();
$table->smallInteger('Mandant');
$table->smallInteger('Kategorie')->nullable();
$table->string('Matchcode', 50);
$table->string('Anrede', 50)->nullable();
$table->string('Name1', 50)->nullable();
});
}
my api content:
[
{"Adresse":"1111","Mandant":"0","Kategorie":"0","Matchcode":"fgh8881","Anrede":"Firma","Name1":"Sample name"},{"Adresse":"2399","Mandant":"0","Kategorie":"0","Matchcode":"fgh8882","Anrede":"Firma","Name1":"Sample name 1"}
]
the problem is i get an error
SQLSTATE[HY000]: General error: 1364 Field 'Adresse' doesn't have a
default value (SQL: insert into addresses () values ())
when i limit the api content to one array i can save it without a problem. But if i have more arrays in my api i get this error.
$fillable property on the model is set.
If your primary key is not auto-incrementing the framework needs to know about it.
class Address extends Model
{
protected $primaryKey = 'Adresse';
protected $fillable = ['Adresse', 'Mandant', 'Kategorie', 'Matchcode', 'Name1'];
public $incrementing = false;
public $timestamps = false;
}
Then to add all of the models:
public function index()
{
$http = new \GuzzleHttp\Client;
$res = $http->request('GET', 'http://localhost:8080/api/address');
$addresses = json_decode($res->getBody(),true);
foreach ($addresses as $address) {
Address::create($address);
}
}
Your API content is essentially 2 records. For mass inserting using eloquent you need to use insert not create
So either
1) have your api return 1 result
2) or change Address::create($addresses); to Address::insert($addresses);
Set Adresse be auto-increment as well with primary key and your issue will be solved or If you do not want to set it to auto-increment then assign it to a default value.
check the table structure of addresses whether it have default value NULL need to change default

Eloquent not linking tables

So I've got 3 tables. But Laravel fails to link the tables to eachother, I feel like I'm missing a really small thing but I can't seem to find it.
Controller
$data = Item::all();
$clipper = $data->first();
dd($clipper->attributes());
Item
protected $table = 'item';
protected $primaryKey = 'item_id';
public $timestamps = false;
public function attributes() {
return $this->hasMany('App\Attributes', 'item_id');
}
Atrributes
protected $table = 'attributes';
protected $primaryKey = 'attr_id';
public $timestamps = false;
public function name() {
return $this->hasOne('App\Attributesname', 'name_id');
}
Attributes Name
protected $table = 'item_attributes';
protected $primaryKey = 'item_attr_id';
public $timestamps = false;
Result of dd
Database design
Laravel links relations fine, see you output parent model is the Item, related model is the Atribute, try this to see related data (not relation) :
$data = Item::all();
$clipper = $data->first();
dd($clipper->attributes);

Getting foreign tables value laravel

here is an example
Table Structure
Game
--id
--game
Posts
--id
--game_id
--post_text
class Posts extends Eloquent {
protected $primaryKey = 'id';
protected $table = 'posts';
public function games() {
return $this->hasOne('games','id');
}
}
class Games extends Eloquent {
protected $primaryKey = 'id';
protected $table = 'games';
public function posts() {
return $this->belongsTo('posts','game_id');
}
}
I need to get the game name of a certain post. How can I get it using eloquent?
here is my initial code
echo $post->games['game'];
but I get the wrong data.
The way it queries is this.
'query' => string 'select * from `games` where `games`.`id` = ? limit 1' (length=52)
'bindings' =>
array (size=1)
0 => int 5
Firstly Eloquent model names are not plural, so by default they should be Game and Post.
Secondly relationship return values must be changed. In hasOne and belongsTo you will need to use model class names like below. I also left out some optional code which is not required for the code to work.
class Post extends Eloquent {
public function game() {
return $this->hasOne('Game');
}
}
class Game extends Eloquent {
public function post() {
return $this->belongsTo('Post');
}
}
Now you can get the game name by $post->game->name

Categories