How can I use relationship with Laravel? - php

My database stockcomment table as below;
id|user_id|stock_id|comment
1 | 10 | 9034 |RC MONSTER CAR
2 | 1 | 9034 |very cool car
My databese user table as below;
id |user_name |
1 | Ufuk ÇAĞLAR |
10 | Mariana Atencio |
How can I relate to each other.
How to access user information with comments?
I want to do output :
[{"id":1,"user _id":1,"stock_id":9034,"comment":RC MONSTER CAR,"user_name":"Ufuk ÇAĞLAR",
"id":2,"user _id":10,"stock_id":9034,"comment":VERY COOL CAR,"user_name":"MARIANA ATANCIO",]

You can define User Model and StockComment
now in User model.
public function stockComments(){
return $this->hasMany(StockComment::class);
}
Now you can access User object with $user->stockComments
Here is an example
$user = User::find($id);
$user->stockComments;
Hope this helps

Assuming you have User and Stock models and users, stocks and stockcomment tables, you can set a relationship from your user model
public function stock() {
return $this->belongsTo(Stock::class)->withPivot('comment');
}
Then in your stock model
public function users() {
return $this->hasMany(User::class)->withPivot('comment');
}
Then you call them:
$stock = User::find($id)->stock; //Stock from this user
//or
$users = Stock::find($id)->users; //Users from this stock
EDIT:
How to access user information with comments?
With using Query Builder:
$data = DB::table('stockcomment')->where('stock_id', 9034)->get();
or if you have StockComment model and a relationship towards Stock on it, you can do:
$data = StockComment::where('stock_id', 9034)->get();
$data will be:
[
{
"id":1,"user_id":1,"stock_id":9034,"comment":RC MONSTER CAR,"user_name":"Ufuk ÇAĞLAR"
},
{
"id":2,"user_id":10,"stock_id":9034,"comment":VERY COOL CAR,"user_name":"MARIANA ATANCIO"
}
]

Define this relationships in StockComment model:
public function user()
{
return $this->belongsTo(User::class);
}
And this relationship in the User model:
public function stockComments()
{
return $this->hasMany(StockComment::class);
}
https://laravel.com/docs/5.5/eloquent-relationships

On the User model, you need to create a hasMany relationship.
public function stockcomments()
{
return $this->hasMany(StockComment::class);
}
Once created, you'll be able to fetch the comments by doing
$user->stockcomments;
This will return a Collection which will allow you to iterate through

You can use joins to achieve desire result, here is your updated code
$result = User::join('stockcomment', 'users.id', '=', 'stockcomment.user_id')
->select('users.id', 'stockcomment.stock_id', 'stockcomment.comment',stockcomment.username)
->get();

Related

How to retrieve records from a table based on many to many relationship using eloquent in Laravel?

I have Three Models: Nationality, Nationality_Opportunity, Opportunity.
The Tables :
-------------------------------------------------------------------
nationalities | nationality_opportunities | opportunities
--------------------------------------------------------------------
id nationality_id id
name opportunity_id name
In Opportunity Model:
public function nationalities(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
{
return $this->belongsToMany(Nationality::class,'nationality_opportunities','opportunity_id','nationality_id');
}
In Nationality Model:
public function opportunities()
{
return $this->belongsToMany(Opportunity::class,'nationality_opportunities','opportunity_id','nationality_id');
}
-What do I want to do ?
I want to retrieve the opportunities records based on their selected nationalities which are sent as an array of ids through the request, so I want to check these ids in the pivot table in order to get their related opportunities records and display them in a Vue js component.
Scope Filter in Opportunity Model:
public function scopeWithFilters($query)
{
return $query->when(count(request()->input('categories', [])), function ($query) {
$query->whereIn('opp_cat_id', request()->input('categories'));
})->when(count(request()->input('nationalities',[])),function ($query){
$query->whereIn('nationalities.nationality_id', request()->input('nationalities'));
});
}
The parameter: nationalities = [1,2,3,5] .
Properties function in api controller:
public function opportunities()
{
$opportunities = Opportunity::withFilters()->get();
return PublicOpportunityResource::collection($opportunities);
}
Your Query is correct but you need to change the way you return the day please follow
$nationalities = [1,2,3,5]; //for temperory ids you can change it
$data= Nationality::with('opportunities')->whereIn('id', $nationalities)->get();
//return it as below
return response()->json($nationalities);
You can simply fetch opportunities with the code below
$nationalities = Nationality::with('opportunities')->whereIn('id', request()->input('nationalities'))->get();
And then you can access the opportunities by iterating over $nationalities or for the first row you can use $nationalities->first()->opportunities, not sure why you're using when in the callback function.
As per the edit you can make this query for your desired result
$nationalities = request()->input('nationalities');
$opportunities = Opportunity::with(['nationalities' => fn($q) => $q->whereIn('nationality_id', $nationalities)])->get();

Laravel framework eloquent relationship query

I have created relationship between 4 tables.
This are my models:
User
BusinessInfo
ElectrcityInfo
GasInfo
This are the primery keys that I am using in my tables:
user_id (to get login users data from BusinessInfo)
contract_id (This also exists in BusinessInfo I am use it to get data from the other two tables for specific records)
Now I want to get all login users data from BusinessInfo table and each BusinessInfo row has its own 1 row data from ElectricityInfo and GasInfo.
When I am use contract_id in model its give me relationship result null.
When it is on user_id its display only 1 ElectrcityInfo with all records.
Controller
$user = Auth::user();
$business = BusinessInfo::where('user_id', $user->id)->first();
$data = $business->electricity()->paginate(6);
return view('Pages.MySite', ['data' => $data]);
BusinessInfo Model
protected $primaryKey = 'contract_id';
public $table = "business_info";
protected $guarded = [];
public $timestamps = false;
public function electricity()
{
return $this->belongsTo('App\Models\ElectricityInfo', 'contract_id');
}
public function gas()
{
return $this->belongsTo('App\Models\GasInfo', 'contract_id');
}
You BusinessInfo model is missing the user relationship. Put this in your code:
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
Your query is not right
When it is on user_id its display only 1 ElectrcityInfo with all records.
This is because you use the first() method wich returns the first object from the collection. You should use this:
$businesses = BusinessInfo::where('user_id', $user->id)->get();
This will return all objects according to the query.
Now you can loop the $business array and access each information
foreach($businesses as $business)
{
$business->electricity()->first(); // this will return all your data from the BusinessInfo relation with the ElectricityInfo model
$business->gas()->first(); // this will return all your data from the BusinessInfo relation with the GasInfo model
}
For more info about the first() method and other methods click here
You also could take a look at the Eloquent: Relationships section to know more about how it works
In your view:
#foreach($businesses as $business)
{
{{$business->electricity()->first()}}
{{$business->gas()->first()}}
}
#endforeach

Laravel relationships get user emails

Hey from my website I'm sending multiple notifications to users, I'm assigning users to a team and then I assign this team to the notifications table.
However when I do SiteNotification::find(1)->notifications() then I get the name of the team, however, I was looking to get the user model and all the details related to that. Is there an easy way to obtain this using Laravel Eloquent relationships?
My DB model and Eloquent model are below;
DB tables;
User
id | username | email
Teams
id | name |
Team Members
team_id | user_id
Site Notifications
site_notification_id | team_id
Model Here:
class SiteNotification extends Model {
public function notifications()
{
return $this->belongsToMany(Team::class, 'site_check_notifications', 'site_check_id', 'team_id');
}
}
Update:
I've tried updating the Team Model as follows;
class Team extends Model
{
public function users()
{
return $this->hasManyThrough(
User::class,
TeamMember::class,
'team_id',
'id'
);
}
}
However this throws an error as follows when running this;
$site = Site::find(1);
foreach( $site->notifications as $notification) {
dd($notification->users);
}
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'team_members.id' in 'on clause' (SQL: select `users`.*, `team_members`.`team_id` from `users` inner join `team_members` on `team_members`.`id` = `users`.`id` where `team_members`.`team_id` = 4)
Any ideas what I'm doing wrong??
I've found a solution which has meant that I do not need to amend my existing database structure and I've found the correct relationship to use.
public function users()
{
return $this->belongsToMany(
User::class,
'team_members',
'team_id',
'user_id'
);
}
Now I can do Site::find(1)->users->pluck('email')
You have to change the model structure... This is how I would have reached your goal... Take it as a "working solution", maybe not the best!
First of all, database. You should have these tables, there is no need to
users => users table
teams => teams table
team_user => pivot table n:n
team_site_notification => pivot table n:n
site_notifications => notifications table
user_site_notification => pivot table n:n
Then you create the related models relations
public class User {
// [...]
public function teams() {
return $this->belongsToMany(Team::class)
}
public function notifications() {
return $this->belongsToMany(SiteNotification::class)
}
}
public class Team {
// [...]
public function users() {
return $this->belongsToMany(User::class)
}
public function notifications() {
return $this->belongsToMany(SiteNotification::class)
}
}
public class SiteNotification {
// [...]
public function teams() {
return $this->belongsToMany(Team::class)
}
public function users() {
return $this->belongsToMany(User::class)
}
}
In your controller, when you create the SiteNotification model, you'll have to associate also the users. For example
public function store(Request $request) {
// Do your stuff
$team = Team::findOrFail($request->your_team_id);
$notification = Notification::create($data);
$notification->teams()->associate($request->your_team_id);
// Retrieve the users from the team... Maybe not everyone should receive a notification
$team->users()->whereIn('id', $user_ids)->get()->pluck('id')
$notification->users()->associate($ids);
}
When you want to get your users list you simple retrive the associated users in this way:
dd($notification->users);
// [ User:{id: 1, '...'}, User:{id: 2}, User:{id: 7} ]
Hope this is what you're looking for!

How to get data from related table in Laravel (one to many)?

I have two tables: users, orders. I try to get all orders for current user.
Users Orders
_____ ______
id | name id | user_id
User model:
public function orders(){
return $this->hasMany("App\Order");
}
Order model:
public function user(){
return $this->hasOne("App\User", 'user_id', 'id');
}
Query in controller:
public function index()
{
$orders = Order::where('user_id', Auth::guard('api')->id())->get();
return response()->json(
$orders->user
);
}
I get NULL result, I do something wrong, because there are related rows in both tables.
If you want to retrieve all the Orders belonging to the current user, try using the following function.
public function index()
{
$orders = Auth::user()->with('Orders')->get()->toArray();//To get the output in array
/* ^ ^
This will get the user | This will get all the Orders related to the user*/
return response()->json($orders);
}
As pointed out by #Martin Heralecký, you would also need to change the hasOne() to belongsTo() in Order Model. See following (copied from #Martin Heralecký answer)
public function user(){
return $this->belongsTo("App\User");// second and third arguments are unnecessary.
}
Why belongsTo():
has_one and belongs_to generally are the same in the sense that they point to the other related model. belongs_to make sure that this model has the foreign_key defined. has_one makes sure that the other model has_foreign key defined.
Your $orders array will look something like this:
User => [
id => 'user id',
name => 'user name'
orders => [
0 => [
//order data
]
1 => [
//order data
]
.
.
.
.
]
]
In Order model you need to use the belongsTo relationship:
public function user()
{
return $this->belongsTo("App\User"); // second and third arguments are unnecessary.
}
In User model you can use hasMany relationship, for example in:
App/User.php
Add
public function orders()
{
return $this->hasMany("App\Order", "user_id", "id");
}
Now you can use this:
return User::find(1)->orders;

Laravel Object queries - 3 tables

I have three tables like this:
**Users**
id
**Posts**
id
user_id
**Favorites**
id
user_id
post_id
Currently, I made it so when I query my posts for display, it pulls all the related user data who created the post with that row which is great! But what I'm trying to do now is also add to see if the user Authorized (Logged in) has favorited the post (row) so I can display to that they already favorited it. I don't want to re-query for every post (i think its called the N+1 problem?). I'm using Laravel4
Post model
class Post extends Eloquent{
public function user(){
return $this->belongsTo('User');
}
User model
public function posts(){
return $this->hasMany('Post');
}
PostsController
public function index()
{
$posts = Post::with('user')->paginate(25);
return View::make('index', compact('posts'));
}
Step 1. Add favorites relationship in Post model.
public function favorites() {
return $this->hasMany('Favorite');
}
When querying the Model.
$auth_user_id = Auth::user()->id;
$posts = Post::with(array('user', 'favorites' => function($query) use ($auth_user_id){
$query->where('user_id', '=', $auth_user_id);
}))->get();
For more information refer to the eager load constraints,
http://laravel.com/docs/eloquent#eager-loading
Adding a many-to-many relationship using the favorites table as pivot would be one approach.
Add favorites relationship in User model:
public function favorites() {
return $this->belongsToMany('Post', 'favorites');
}
You should then be able to get all favorites by simply accessing
Auth::user()->favorites
To find whether the current post is a favorite, use
$isFavorite = Auth::user()->favorites->has($post->id);

Categories