Cannot make it work to get many to many related table by custom pivot table in laravel5.6 - php

My Post model has this function not working
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = "wp_posts";
protected $primaryKey = "ID";
public function taxonomies()
{
return $this->belongsToMany('App\Models\TermTaxonomy', 'wp_term_relationships', 'object_id', 'term_taxonomy_id');
}
}
I wanna get the taxonomies data from post through pivot table but I can't.
I connected Laravel to my WP database and tried to get Taxonomies from Posts.
Posts and Taxonomies are many to many relationship with 'wp_term_relationships' pivot table.
post table has 'ID' primary key
taxonomy table has 'term_taxonomy_id' primary key
The pivot table is like
'wp_term_relationships'
- 'object_id' ... related to Post.ID
- 'term_taxonomy_id' ... related to Taxonomy.term_taxonomy_id
I don't know why this not working. If anyone knows plz help me. Thank you so much.
Add
// Taxonomy
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TermTaxonomy extends Model
{
protected $table = 'wp_term_taxonomy';
protected $primaryKey = 'term_taxonomy_id';
}
// in the Controller
public function profile($id)
{
$teacher = User::isTeacher()->where(['ID' => $id])->with(['posts' => function ($query) {
$query->where('post_type', 'answer')->take(3);
}])->firstOrFail();
$data = [
'teacher' => $teacher
];
return view('teacher.profile', $data);
}
// in the View
#foreach($teacher->posts as $answer)
#php
foreach($answer->postParent->taxonomies as $taxonomy) {
print($taxonomy->term_id);
}
#endphp
#endforeach

The actual problem was not how to define many to many relationship,
it was how to retreive the relation data.
public function profile($id)
{
$teacher = User::isTeacher()->where(['ID' => $id])->with(['posts' => function ($query) {
$query->where('post_type', 'answer')->take(3)->with(['postParent' => function ($query) {
$query->where('post_type', 'question')->with(['taxonomies' => function ($query) {
$query->where('taxonomy', 'question_category')->with(['term']);
}]);
}]);
}])->firstOrFail();
$data = [
'teacher' => $teacher
];
return view('teacher.profile', $data);
}

Related

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.

How to insert pivot table in case of many to many relation? (Laravel 5.3)

My form to add data is like this :
When klik save, It will call controller
My controller is like this :
public function store(Request $request)
{
$param = $request->only('account_name','account_number','bank_id','branch');
$result = $this->user_service->addUserBank($param);
if($result)
$status='success';
else
$status = 'failed';
return redirect('member/profile/setting/account')->with('status',$status);
}
My service is like this :
public function addUserBank($param)
{
$instance = User::where('id', '=', auth()->user()->id)->first();
$param['user_id'] = auth()->user()->id;
$param['status'] = 0;
$instance->banks()->attach([
'status' => $param['status'],
'account_name' => $param['account_name'],
'account_number' => $param['account_number'],
'branch' => $param['branch']
]);
return $result;
}
My model user is like this :
<?php
namespace App;
use App\Models\MasterData;
use Collective\Html\Eloquent\FormAccessible;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable, FormAccessible;
protected $fillable = [
'name', 'email', 'password', 'api_token','birth_date','mobile_number','gender','full_name'
];
protected $hidden = [
'password', 'remember_token',
];
public function banks()
{
return $this->belongsToMany(MasterData::class, 'users_banks', 'user_id', 'bank_id') ->withPivot('status','account_name','account_number','branch')->withTimestamps();
}
}
So I have 3 table : users table, users_banks table (pivot table), and master_datas table
List of the names of the banks located in the master_datas table with type bank
Users table have field id, name, email, password etc => See model user
Master_datas table have field id (this is bank id), name (this is bank name), type (there exist type of bank, order status etc. So, get type = bank)
Users_banks table have field id, user_id, bank_id, status, account_name, account_number, branch
When run, it does not successfully insert into the pivot table (table users_banks).
It looks like my way to insert into the pivot table, not true.
Can you help me?
Additional
Table Master_datas is like this :
The problem is that you are not passing bank_id in your addUserBank() method. you can do it as:
public function addUserBank($param)
{
$param['status'] = 0;
auth()->user()
->banks()
->attach($param['bank_id'], array_only($param, ['status', 'account_name', 'account_number', 'branch']);
return true;
}
Note: You don't need to set user_id explicitly here as Laravel will automatically do it for you.
Docs
Create UserBank model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserBank extends model
{
protected $table = 'user_banks';
protected $fillable = ['user_id','bank_id'];
}
And then populate the table from controller:
public function store(Request $request)
{
$param = $request->only('account_name','account_number','bank_id','branch');
$result = $this->user_service->addUserBank($param);
if($result)
{
$pivot=new UserBank();
$pivot->user_id=auth()->user()->id;
$pivot->bank_id=$request->bank_id;
if($pivot->save())
{
$status='success';
}
}
else
{
$status = 'failed';
}
return redirect('member/profile/setting/account')->with('status',$status);
}

How To Update Laravel hasMany Relationship Models?

I've been trying to wrap my head on figuring out how to update my hasMany relationship model. I can easily create new relationships but when I try to update my relationship model it does not work? Does laravel push() method still work? Can anyone help please? For example I want to update my Taxonomy Table thats related to my Products table within my Controller. I have a code snippet below::
Product.php
class Product extends Model
{
protected $fillable = [
'product_category', 'product_subcategory', 'product_name',
'product_price', 'product_id', 'product_description', 'product_image'
];
protected $primaryKey = 'product_id';
public $incrementing = false;
public function addTaxonomiesToProduct()
{
return $this->hasOne('App\Taxonomies', 'product_id', 'product_id');
}
}
Taxonomies.php
class Taxonomies extends Model
{
protected $fillable = ['product_category', 'product_subcategory'];
protected $primaryKey = 'product_id'; // or null
public $incrementing = false;
public function product()
{
return $this->belongsTo(Product::class);
}
}
EditProductController.php
class EditProductController extends Controller
{
public function update(Request $request, Product $product)
{
$product_size = array();
foreach ($request->product_size as $key => $value)
{
array_push($product_size,$value);
}
$product->update([
'product_name' => $request->product_name,
'product_price' => $request->product_price,
'product_description' => $request->product_description,
'product_size' => serialize($product_size),
'product_image' => $product_image_path,
]);
/**
* Go the products table,
* Get the product based off its product_id,
* and then update this products taxonomy
**/
$taxonomies = Product::find($product->product_id);
$taxonomies->addTaxonomiesToProduct->product_subcategory = "Mens Shoes";
$taxonomies->push();
}
}
****Update Issued Solved****
By changing hasMany() to hasOne() within my Products table, my taxonomies table updated correctly.
I think you don't fully understand the way Laravel Eloquent relationships work. First off, you need to define the relationship in both models.. Your Taxonomy model has this, but your Product model should have:
public function taxonomies()
{
return $this->hasMany('App\Taxonomies', 'product_id', 'product_id');
}
Then to update a Product's taxonomies, you'd have something like...Uh, I'm not sure what you're trying to achieve here, especially with the way you chained the product_subcategory, so I can't rightly say, but do see the documentation

Add values to pivot table laravel

When I want to save a reaction to a ticket I've three tables (in laravel):
-Tickets
-Reaction
-Reaction_Tickets (pivot table)
When I want to save a reaction I do it like this:
public function addReaction(Request $request, $slug)
{
$ticket = Ticket::whereSlug($slug)->firstOrFail();
$reaction = new reactions(array(
'user_id' => Auth::user()->id,
'content' => $request->get('content')
));
return redirect('/ticket/'.$slug)->with('Reactie is toegevoegd.');
}
But now of course it's not added to the pivot table. And I can't add it because I don't have a model of it. What's the right way of doing this?
EDIT:
-Tickets
public function reactions()
{
return $this->belongsToMany('App\reactions');
}
-Reactions
public function tickets()
{
return $this->hasOne('App\tickets');
}
From the Laravel documentation, you need to save and attach the Reaction to the Ticket:
$reaction = new reactions(array(
'user_id' => Auth::user()->id,
'content' => $request->get('content')
));
$reaction->save(); // Now has an ID
$tickets->reactions()->attach($reaction->id);
In your Ticket model, you need to have the relationship defined:
class Ticket extends Model {
protected $table = "tickets";
public function reactions(){
return $this->belongsToMany("App\Reaction");
}
}
And you should have the inverse defined on Reaction:
class Reaction extends Model {
protected $table = "reactions";
public function tickets(){
return $this->belongsToMany("App\Ticket");
}
}
If your models are set-up like so, you shouldn't have any issue attaching the new Reaction to your existing Ticket via your pivot table.

Laravel save many-to-many relationship in Eloquent mutators

I've got 2 models with a many-to-many relationship. I want to be able to set a specific attribute with an array of ids and make the relationship in the mutator like this:
<?php
class Profile extends Eloquent {
protected $fillable = [ 'name', 'photo', 'tags' ];
protected $appends = [ 'tags' ];
public function getTagsAttribute()
{
$tag_ids = [];
$tags = $this->tags()->get([ 'tag_id' ]);
foreach ($tags as $tag) {
$tag_ids[] = $tag->tag_id;
}
return $tag_ids;
}
public function setTagsAttribute($tag_ids)
{
foreach ($tag_ids as $tag_id) {
$this->tags()->attach($tag_id);
}
}
public function tags()
{
return $this->belongsToMany('Tag');
}
}
<?php
class Tag extends Eloquent {
protected $fillable = [ 'title' ];
protected $appends = [ 'profiles' ];
public function getProfilesAttribute()
{
$profile_ids = [];
$profiles = $this->profiles()->get([ 'profile_id' ]);
foreach ($profiles as $profile) {
$profile_ids[] = $profile->profile_id;
}
return $profile_ids;
}
public function profiles()
{
return $this->belongsToMany('Profile');
}
}
However the setTagsAttribute function isn't working as expected. I'm getting the following error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'profile_id' cannot be null (SQL: insert intoprofile_tag(profile_id,tag_id) values (?, ?)) (Bindings: array ( 0 => NULL, 1 => 1, ))
You can't attach many-to-many relations until you've saved the model. Call save() on the model before setting $model->tags and you should be OK. The reason for this is that the model needs to have an ID that Laravel can put in the pivot table, which needs the ID of both models.
It looks like you're calling the function incorrectly or from an uninitialized model. The error says that profile_id is NULL. So if you're calling the function as $profile->setTagsAttribute() you need to make sure that $profile is initialized in the database with an ID.
$profile = new Profile;
//will fail because $profile->id is NULL
//INSERT: profile->save() or Profile::Create();
$profile->setTagsAttribute(array(1,2,3));
Additionally, you can pass an array to the attach function to attach multiple models at once, like so:
$this->tags()->attach($tag_ids);
You can also pass it the model instead of the ID (but pretty sure array of models won't work)
Try using the sync method:
class Profile extends Eloquent {
protected $fillable = [ 'name', 'photo', 'tags' ];
protected $appends = [ 'tags' ];
public function getTagsAttribute()
{
return $this->tags()->lists('tag_id');
}
public function setTagsAttribute($tag_ids)
{
$this->tags()->sync($tagIds, false);
// false tells sync not to remove tags whose id's you don't pass.
// remove it all together if that is desired.
}
public function tags()
{
return $this->belongsToMany('Tag');
}
}
Don't access the tags through the tags() function, rather use the tags property. Use the function name if you want to pop additional parameters onto the relationship query and the property if you just want to grab the tags. tags() works in your getter because you're using get() on the end.
public function setTagsAttribute($tagIds)
{
foreach ($tagIds as $tagId)
{
$this->tags->attach($tagId);
}
}

Categories