Many to many tables how to view on Laravel - laravel

I have this three tables :
Table 1. users
'first_name', 'last_name', 'bio', 'image', 'email', 'password', 'user_group','remember_token',
Table 2. professions
'id', 'title',
Table 3 user_profesions
'id','user_id', 'profession_id'
I combined the users table with user_professions table like this:
public function index(){
$mentors = User::where('user_group', 2)->get();
$all_professions = Profession::get();
foreach($mentors as $mentor) {
$mentor->professions = UserProfession::where('user_id', $mentor->id)->get();
}
dd($mentors);
return view('mentors.list-of-mentors')->with(['mentors'=>$mentors, 'all_professions' => $all_professions]);
}
So it gives me this when I die dump
I am also passing the all professions from professions table.
In view I am doing it like this
#foreach($mentors as $mentor)
{{$mentor->first_name}}
#foreach($all_professions as $profession)
{{$profession}}
#endforeach
#endforeach
I am stuck here I don't know how to make the professions for that particular user to appear.. Can someone please help me..?

You can use eloquent ManyToMany relationship to fetch data between User and Profession model. And for that you have to define it like this
User Model
public function professions()
{
return $this->belongsToMany('App\Profession','user_profesions');
}
Profession Model
public function users()
{
return $this->belongsToMany('App\User','user_profesions');
}
Now fetch it like this in controller
$mentors = User::with('professions')->where('user_group', 2)->get();
return view('mentors.list-of-mentors')->with('mentors',$mentors);
In view you can use it like this
#foreach($mentors as $mentor)
{{$mentor->first_name}}
#foreach($mentor->professions as $profession)
{{$profession}}
#endforeach
#endforeach
Check here https://laravel.com/docs/5.6/eloquent-relationships#many-to-many

Add relationship mathods to your models.
UserModel
public function professions()
{
return $this->hasMany(Profession::class);
}
ProfessionModel:
public function users()
{
return $this->hasMany(User::class);
}
And now you can do this:
$user = User::where('user_group', 2)->with('professions')->get();
dd($user->professions);

Related

laravel 8 store request with foreign key user_id not working

I would like to store the corresponding logged in user when adding a new School data. What I'm trying to do is store the logged in user_id in the schools table, in order to know on who added the school data. I have a users table already, which will establish the relation in the schools table.
My goal is when an admin is logged in, he/she can see all of the School records, otherwise if it's a user, then only fetch the records he/she added. The problem is that I can't figure out on when and where to insert the user_id data during the store request as I'm getting an error "user id field is required". Here's what I've tried so far:
Migration:
class CreateSchoolsTable extends Migration
{
public function up()
{
Schema::create('schools', function (Blueprint $table) {
$table->id();
$table->string('school_name');
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->timestamps();
});
}
}
School Model:
class School extends Model
{
use HasFactory;
protected $fillable = ['school_name', 'user_id'];
public function User() {
return $this->belongsTo(User::class);
}
}
Store Request:
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255',
'user_id' => 'required|exists:users,id'
];
}
}
Controller:
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
$school_data = $request->validated();
$user_id = \Auth::user()->id;
$school_data['user_id'] = $user_id;
School::create($school_data );
return Redirect::route('schools.index');
}
}
Any inputs will be of big help! Thanks.
Laravel has elegant way to bind authenticated user_id. Remove user_id from request class and chaining method. Also setup relationship from User model to School Model
Form Request Class
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255',
];
}
}
User Model
protected $fillable = ['school_name', 'user_id'];
...
// new line
public function schools() {
return $this->hasMany(School::class);
}
Your Controller
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
auth()->user()->schools()->create($request->validated());
return Redirect::route('schools.index');
}
}
UPDATE ANSWER
Since user_id value is school name (based on image link from comment), probably there's something wrong either in User or School model. Here the quick fix
Your Controller
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
auth()->user()->schools()->create(
array_merge(
$request->validated(),
['user_id' => auth()->id()]
)
);
return Redirect::route('schools.index');
}
}
You can add 'created_by' and 'updated_by' fields to your table. so you can register in these fields when additions or updates are made.
Then you can see who has added or updated from these fields.
class School extends Model
{
use HasFactory;
protected $fillable = ['school_name', 'user_id', 'created_by', 'updated_by'];
public function User() {
return $this->belongsTo(User::class);
}
}
Your controller part is correct but since you get the logged in user, you wont be having user_id in the request. So you should remove the rules about user_id from your StoreSchoolRequest.
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255'
];
}
}
Problem is here ..
$school_data = $request->validated();
Since you are using $request->validated()..
You have to safe()->merge user_id into it , here Docs : .
$validated = $request->safe()->merge(['user_id' => Auth::user()->id]);
Then put this $validated into create query , Thanks. –

Laravel query builder with the User and Auth

How to List all rows from a table (agendas) in my DB where records are saved by the connected user.I'm using default Auth from Laravel.
public function index ($id = null)
{
$agendas = Agenda::where('id', Auth::user()->id)->get();
$users = User::all();
return view('admin.agendas.index', compact('agendas','users','id'));
}
My controller here.
Need help
Assuming
agendas table (containing records for Agenda model) has a column user_id which references the id column on users table
User hasMany Agenda
Agenda belongTo User
class User extends Model
{
public function agendas()
{
return $this->hasMany(Agenda::class);
}
//... rest of class code
}
class Agenda extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
//... rest of class code
}
public function index($id = null)
{
$user = User::with('agendas')->findOrFail(auth()->id());
return view('admin.agendas.index', [
'user' => $user,
'agendas' => $user->agendas,
'id' => $id
]);
}
Your User model should have a relationship:
public function agendas()
{
return $this->hasMany(Agenda::class);
}
In your controller, you could then simplify the use as such:
public function index (Request $request, $id = null)
{
$agendas = $request->user()->agendas;
$users = User::all();
return view('admin.agendas.index', compact('agendas','users','id'));
}
if you wanna get data related to another data , you have to join those tables together by a field. in this case i guess you have a column in Agenda table named 'user_id'.
you have two way :
join tables in your Model.
search in Agenda table in your controller
if you want to use joining your tables from model :
// in App\User.php
...
class User ...{
...
public function Agenda(){
return $this->hasMany(Agenda::class);
}
...
}
...
then you can access to all of "Agenda" from everywhere like this :
Auth()->user()->agenda
if you want to search in table from your controller you can do :
Agenda::where('id', Auth::user()->id)
you can read more about eloquent-relationships in : https://laravel.com/docs/8.x/eloquent-relationships

Query Laravel Relationship

I have 3 Model
In Purchase Model
protected $fillable = [
'name', 'date', 'description', 'active', 'supplier', 'total', 'paid', 'purchase_status', 'payment_status',
];
public function product()
{
return $this->belongsTo(\App\Product::class);
}
public function order()
{
return $this->belongsTo(\App\Order::class);
}
In Order Model
protected $fillable = [
'name', 'quantity', 'unit_cost', 'discount', 'tax', 'sub_total'
];
public function order_items()
{
return $this->belongsTo(\App\OrderItem::class);
}
In my OrderItem Model
protected $fillable = ['active', 'description', 'quantity', 'discount', 'unit_price'];
public function order()
{
return $this->belongsTo(\App\Order::class);
}
Is it possible to query Order_Items From Purchases trough Orders Relationship in Laravel?
Oh, i found my answer...
In Order Model
i changed belongsTo to hasMany
protected $fillable = [
'name', 'quantity', 'unit_cost', 'discount', 'tax', 'sub_total'
];
public function order_items()
{
return $this->hasMany(\App\OrderItem::class);
}
Yes you can write this relations in your models and write the query like this:
Purchase
public function order()
{
return $this->belongsTo('App\Models\Order', 'order_id', 'id');
}
Order_Item
public function order()
{
return $this->belongsTo('App\Models\Order', 'order_id', 'id');
}
Order
public function order_items()
{
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
public function purchases()
{
return $this->hasMany('App\Models\purchase', 'order_id', 'id');
}
Now you can use this query:
$purchase = \App\Models\Purchase::first();
$order_items = $purchase->order->order_items;
I see that you've fixed the relationship Order -> OrderItem of belongsTo to hasMany. But the question was also about how to query through relationships so I'll just add up to this so it could be useful to other users here.
Now you could do
$order_items = $purchase->order->order_items
to get the order items of the purchase.
However you should consider that this would execute further queries to the DB. One for fetching the order and then another one for fetching the order_items. If you're looping through a list of purchases, this could escalate quickly and end up making too much DB queries and affect the performance of your application.
The solution is eager loading.
You could do either pre-fetch the order and items along with the purchase like this:
$purchase = Purchase::with('order.order_items')->find(1);
or if you've already fetched the purchase, then you could do:
$purchase->load('order.order_items');
Then when getting the order items in your code like this
$purchase->order->order_items, you have no additional queries to the DB.

Laravel relations pivot table name trouble

in my app I have 2 conversations types: normal private conversations between users and conversations for people which are interested of user product.
In my User model I declared relations like:
public function conversations()
{
return $this->belongsToMany('App\Conversation', 'conversation_user');
}
public function conversationsProduct()
{
return $this->belongsToMany('App\ConversationProduct', 'conversation_product_user', 'user_id', 'product_id');
}
Where 'conversation_user' and 'conversation_product_user' are pivot tables between 'users'-'conversations' and 'users'-'conversations_product' tables.
My conversation_user pivot table has conversation_id and user_id table properties, but conversation_product_user pivot table has additional property product_id.
In my Conversation Model I have:
public function users()
{
return $this->belongsToMany('App\User');
}
public function messages()
{
return $this->hasMany('App\Message');
}
In ConversationProduct Model I wrote:
protected $table = 'conversations_product';
public function users()
{
return $this->belongsToMany('App\User', 'conversation_product_user');
}
public function messages()
{
return $this->hasMany('App\MessageProduct');
}
In my ConversationProductController I have method to find user conversations:
public function showUserConversationsProduct(Request $request){
$user_id = $request->user_id;
//var_dump($user_id);
$userData = User::where('id', $user_id)->with('conversationsProduct')->first();
}
And there is my problem: In controller ->with('conversationsProduct') don't take relation for conversation_product_user, but for conversation_user pivot table. I can't handle it why its happen if I add second parameter as 'conversation_product_user' in my relation:
public function conversationsProduct()
{
return $this->belongsToMany('App\ConversationProduct', 'conversation_product_user', 'user_id', 'product_id');
}
I need protected $table = 'conversations_product'; to point my ConversationsProductController#store where to save conversation, but I think that can be problem with recognise proper relation.
I really appreciate any help. I attach photo of my db relations.

Trying to retrieve posts from table by category slug

Hello i am trying to loop posts that are associated to each category by the slug. It works when i use the ids but when i change my controller function to search by slug it retrieves the slug but does not load the foreach loop.
I have tried so many methods and i don't know where i am going wrong please help.
Category Model :
protected $table = 'post_categories';
public function posts()
{
return $this->hasMany('App\Post', 'id', 'name', 'catslug');
}
Post Model
public function user()
{
return $this->belongsTo('App\User');
}
public function postCategories()
{
return $this->belongsTo('App\PostCategory');
}
Controller
public function getPostCategory($catslug) {
$postCategories = PostCategory::with('posts')
->orderBy('name', 'asc')
->where('catslug', '=', $catslug)
->first();
return view ('articles.category.categoriesposts')->with('postCategories', $postCategories);
}
Route
Route::get('articles/category/{catslug}', [
'uses' => 'ArticlesController#getPostCategory' ,
'as' => 'PostCategory'
] );
View
#foreach($postCategories->posts as $post)
<h4>{{ substr($post->title, 0, 50) }}</h4>
<p>{{ substr($post->body, 0, 90) }}</p>
#endforeach
When i use id there is no problem i cant see what i am doing wrong any feedback will be truly appreciated
Thanks
Ash
Save category id in posts table insted of category name or slug.
Change in post category model:
public function posts()
{
return $this->hasMany('App\Post', 'category_id');
}
Your controller method:
public function getPostCategory($catslug)
{
$postCategories = PostCategory::with('posts')->where('catslug', $catslug)->first();
return view('articles.category.categoriesposts')->with('postCategories', $postCategories);
}
If you want to order posts by name then add orderBy() in relationship :
public function posts()
{
return $this->hasMany('App\Post', 'category_id')->orderBy('name', 'asc');
}

Resources