laravel and pivot table - php

I have 3 tables
Game(id, name), GameCategory(game_id, category_id), Category(id, title).
Partial code of classes:
class Game extends \Illuminate\Database\Eloquent\Model
{
protected $fillable = [
'name',
'title'
];
public function categories()
{
return $this->hasMany('VanguardLTE\GameCategory', 'game_id');
}
}
class Category extends \Illuminate\Database\Eloquent\Model {
protected $fillable = [
'title'
];
public function games()
{
return $this->hasMany('VanguardLTE\GameCategory', 'category_id');
}
}
class GameCategory extends \Illuminate\Database\Eloquent\Model {
protected $fillable = [
'game_id',
'category_id'
];
public function category()
{
return $this->belongsTo('VanguardLTE\Category');
}
public function game()
{
return $this->belongsTo('VanguardLTE\Game');
}
}
I need to select category titles for selected $game
This code give me only category_id.
$g_categories = $game->categories->pluck('category_id')->toArray();
This code not working:
$g_categories = $game->categories->category->pluck('title')->toArray();
As You mentioned to do
$g_categories = $game->categories->pluck('category_id')->toArray();
error_log('game_id'.$game->id.' category_ids:'.implode(",", $g_categories));
$g_titles = $game->categories->pluck('title')->toArray();
error_log('game_id'.$game->id.' category_titles:'.implode(",", $g_titles));
This will result with log like this:
game_id1907 category_ids:39,48
game_id1907 category_titles:,
From database side we see that data(title) is filled:
select g.id, g.name, g.title, c.id, c.title
from w_games g
join w_game_categories gc ON gc.game_id = g.id
join w_categories c ON c.id = gc.category_id
where g.id = 1907;
id
name
title
id
title
1907
OceanRulerSW
Ocean Ruler
39
Skywind
1907
OceanRulerSW
Ocean Ruler
48
Fish
Title in game is not necessary in this case but I added it here because have the same column name like title in categories.

You are accessing undefined relation .It should be
$g_categories = $game->categories->pluck('title')->toArray();

This line of code is incorrect and should be as follow:
$g_categories = $game->categories()->pluck('title')->toArray();
you did not add parentheses for categories.

The best solution is to use laravel way:
public function categories()
{
return $this->belongsToMany('VanguardLTE\Category');
}
public function games()
{
return $this->belongsToMany('VanguardLTE\Game');
}
In this way you should name your table as
category_game
and no need to define model for the intermediate table and you can simply access it through
$game->categories->pluck('title')->toArray();
in case you have any data in the pivot table just add ->withPivot('column_name') to your relationship
Refer to Laravel documentation for details

Related

Unable to fetch results from hasManyJson Using staudenmeir / eloquent-json-relations

I have been working on two tables Category & Product.
In Category Model I have a relationship like
class Category extends Model
{
use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;
public function products(){
return $this->hasManyJson(Product::class,'category_ids[]->id');
}
}
In Products Model I have a relationship like
class Product extends Model
{
use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;
protected $casts = [
'category_ids'=>'json',
];
public function products(){
return $this->belongsToJson(Category::class,'category_ids[]->id');
}
}
Now in my controller when I'm doing trying to get count of each categories product, it is giving me Empty results, below is my controller code.
public function two_category()
{
$list = Category::where('home_status', true)->get();
foreach($list as $ls){
echo $ls->name.' '.count($ls->products).'<br>';
}
dd('ended');
}
This is giving -
Category1 0
Category2 0
And finally this is how my column in product table looks like.

How to get only active element from many to many relationship with translation in laravel

I have a problem with a many to many relationship and the translations of the terms.
I have 4 tables:
products
- id, price, whatever
products_lang
- id, product_id, lang, product_name
accessori
- id, active
accessori_lang
- id, accessori_id, lang, accessori_name
I'm trying to assign accessories to products with an intermediate table named:
accessori_products
this is the model for Product:
class Product extends Model {
protected $table = 'products';
public function productsLang () {
return $this->hasMany('App\ProductLng', 'products_id')->where('lang','=',App::getLocale());
}
public function productsLangAll() {
return $this->hasMany('App\ProductLng', 'products_id');
}
public function accessori() {
return $this->belongsToMany('App\Accessori', 'accessori_products');
}
}
this is the model for productLng:
class ProductLng extends Model {
protected $table = 'products_lng';
public function products() {
return $this->belongsTo('App\Product', 'products_id', 'id');
}
}
Then I have the model for Accessori:
class Accessori extends Model {
protected $table = 'accessori';
public function accessoriLang() {
return $this->hasMany('App\AccessoriLng')->where('lang','=',App::getLocale());
}
public function accessoriLangAll() {
return $this->hasMany('App\AccessoriLng');
}
public function accessoriProducts() {
return $this->belongsToMany('App\Products', 'accessori_products', 'accessori_id', 'products_id');
}
}
And the model for AccessoriLng:
class accessoriLng extends Model {
protected $table = 'accessori_lng';
public function accessori() {
return $this->belongsTo('App\Accessori', 'accessori_id', 'id');
}
}
I get the results by this:
$products = Product::has('accessori')->with([
'productsLang ',
'accessori' => function ($accessori){
$accessori->with([
'accessoriLang'
]);
}
])->get();
return $products;
but I want to get only the active accessories something like where accessori.active = 1 but I really don't know where to put it. I've tried in different way but I'm stuck on it by 2 days.
IIRC you don't need a model for the intermediate table on your many to many relationships.
If you want to return Products where Accessori is active you can use whereHas on the Product model.
$prod = Product::whereHas('accessori', function($query) {
$query->where('active', 1);
})->get();
Where the $query param will be running on the Accessori model.
You can do the inverse as well with Accessori to Product.
$acessoris = Accessori::where('active', 1)->whereHas('accessoriProduct')->with(['accessoriLang', 'accessoriProducts.productsLang'])->get();

In Laravel Eloquent create method I am not able to save the data in database

I have Three models:
Language
Article
Category
The Article table has two foreign keys category_id and Language_id. Language-Model has "One to Many" Relationship with Article-Model, Similarly Category-Model has "One to Many" Relationship with Article-Model.
My Category model:
class Category extends Model
{
protected $fillable = [
'category_name',
];
public function articles(){
return $this->hasMany('App\Article');
}
}
My Language model:
class Language extends Model
{
protected $fillable = [
'language_name'
];
public function articles(){
return $this->hasMany('App\Article');
}
}
My Article model:
class Article extends Model
{
protected $fillable = [
'language_id','category_id','category_name','article_title',
'article_desc','source_from','source_url','video_link',
'audio_url','author_name','article_image_url','like_count'
];
public function languages(){
return $this->belongsTo('App\Language');
}
public function categories(){
return $this->belongsTo('App\Category');
}
}
How can I insert in the database using Laravel Eloquent?
$Article = new Article (
[
'article_image_url' => $img_url ,
'audio_url' => $audio_url,
'category_name'=>$category_name ,
'article_title'=>$request->article_title,
'article_desc'=>$request->article_desc,
'source_from'=>$request->source_from,
'source_url'=>$request->source_url,
'video_link'=>$request->video_link,
'author_name'=>$request->author_name,
'like_count'=>'0',
]
);
$language = new Language;
$category = new Category;
$language->articles()->save($Article);
language_id doesn't have a default value; it is foreign key.

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

How to use the `where` method along with the `with` method in laravel 4?

Given the following, very simple, example:
Country Class
class Country extends Eloquent {
protected $table = "countries";
protected $fillable = array(
'id',
'name'
);
public function state() {
return $this->hasMany('State', 'country_id');
}
}
State Class
class State extends Eloquent {
protected $table = "states";
protected $fillable = array(
'id',
'name',
'country_id' #foreign
);
public function country() {
return $this->belongsTo('Country', 'country_id');
}
}
How can I list all the states, based on the id or the name of the country.
Example:
State::with('country')->where('country.id', '=', 1)->get()
The above returns an area, as country is not part of the query (Eloquent must attach the join later, after the where clause).
I think you're either misunderstanding the relations or over-complicating this.
class Country extends Eloquent {
public function states() {
return $this->hasMany('State', 'state_id');
}
}
$country = Country::find(1);
$states = $country->states()->get();

Categories