How to retrieve a record from a parent table based on its id on a child table - php

I have two related models in a job listing application, Company and Listing. The relationship between them is that company may have listing and a listing must have exactly one company.
class Company extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'description',
'email',
'website',
'logo',
'address',
'city',
'state',
];
//Relationship to Listing
public function listings(){
return $this->hasMany(Listing::class, 'company_id');
}
//Relationship to company_image
public function company_image(){
return $this->hasMany(CompanyImage::class, 'company_id');
}
//Relationship to User
public function user(){
return $this->belongsTo(User::class, 'user_id');
}
}
The listing model is defined as
class Listing extends Model
{
use HasFactory;
//Relationship to User
public function user(){
return $this->belongsTo(User::class, 'user_id');
}
//Relationship to Company
public function company(){
return $this->belongsTo(Company::class, 'company_id');
}
I tried
public function edit(Listing $listing)
{
$cid = $listing->only(['id']); //to get the id of the company from the listings table
$cid = $cid['id'];
$comp = Company::orderby('name','Asc')->get(); // this list all company in a select field
$company = Company::whereHas('listings', function ($query) { //to get record of the company using the $cid from the listings table
$query->where('listings.id','=',$cid);
})->get();
dd($company); //to check the value returned.
// return view('listings.edit',[
// 'listing' => $listing,
// 'company' => $company,
// 'companys' => $comp
// ]);
}
i get an Undefined variable $cid when i use it like so where('listings.id','=',$cid).
i get null when i use it like so where('listings.id','=','$cid').
I want to get a result like
SELECT companies.name, companies.logo FROM companies join listings on listings.company_id = companies.id where listings.id = 4
which looks like:
enter image description here

You get the error because you need to pass the variable to closure.
You can pass the variable using use($variable) after function()
$company = Company::whereHas('listings', function ($query) use ($cid){
$query->where('listings.id','=',$cid);
})->get();

Just use your current code and access listing as below:
$some_id = 1;
$data = App\Models\Listing::find($some_id);
//For Name
$data->name;
//For images
$data->company->company_image;

Related

Conditionally append attribute to model in laravel

Is it possible to append an attribute to my model whenever a model scope is called?
For example in my controller I want to call a scope to append those dynamic attribute like :
$Media_query = OutDoorMedia::query();
$Media_query->orderby('created_at', 'desc');
$Media_query->PreviouslyOrdered();
$Media = $Media_query->get();
And in my model I want to do something like :
class OutDoorMedia extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'id',
'user_id',
'address',
'location',
'media_type',
];
}
class scopePreviouslyOrdered extends OutDoorMedia
{
public $appends = ['previously_ordered'];
public function getPreviouslyOrderedAttribute()
{
if ($this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id')->Where(function ($query) {
$query->where('status', MEDIA_ORDER_CHECKOUT_STATUS)
->orWhere('status', STATUS_TO_PAY);
})->exists()) {
return true;
} else {
return false;
}
}
}
But it's not working and I know it's wrong, How to achieve this?
I solved this problem with help of #apokryfos but with a bit tweak. hope this reduce wasting others time.
Instead of appending attributes on the model I have appended the said attribute to my model by the eloquent magic method :
$Media_query = OutDoorMedia::query();
$Media_query->orderby('created_at', 'desc');
$Media = $Media_query->get()->each(function ($items) {
$items->append('previously_ordered');//add this attribute to all records which has the condition
});
In Model As apokryfos said I have put these two methods:
public function PreviousOrders() {
return $this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id');
}
public function getPreviouslyOrderedAttribute() {
return $this->PreviousOrders()->exists();
}
But I don't need this method and I had to remove it from the model because if it exist in model it will automatically append to model:
public $appends = [ 'previously_ordered' ];
I think there's a misunderstanding on how scopes should work. A scope is basically like a shortcut query for a model. You are using it to test existance of a relationship but there's a better way to do that using whereHas
Here's how you would achieve this using a relationship:
class OutDoorMedia extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'id',
'user_id',
'address',
'location',
'media_type',
];
public function previousOrders() {
return $this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id');
}
public function getPreviouslyOrderedAttribute() {
return $this->previousOrders()->exists();
}
}
Then you simply do:
$Media_query = OutDoorMedia::whereHas('previousOrders')
->orderby('created_at', 'desc');
If you what the dynamic attribute appended on the model automatically you can just add the following to the model:
public $appends = [ 'previously_ordered' ];
I guess if you want the best from both worlds you can do:
class OutdoorMediaWithPreviouslyOrdered extends OutDoorMedia {
public $appends = [ 'previously_ordered' ];
}
Then when you need the appending model you can use :
$Media_query = OutdoorMediaWithPreviouslyOrdered ::orderby('created_at', 'desc');

I want to acquire the relation value with the store when searching for a category in Laravel5.6

thank you view my question.
I would like to retrieve information on the tag table relation with the store with many-to-many when searching for a category
I created Store-table, Category-table, Tag-table.
The store-table and the category-table are connected by a many-to-many relation. The tag-table is the same.
I was able to search for categories and get information on businesses that are relation- ed, but I do not know how to get information on tags that are relations with stores.
So, I try this idea. search categories → get storeID from relation data→ storeID search → return shop data that hit.
However, I do not know how to get storeID in the store data acquired by category search
How can I write the code?
please help me.
sorry, bat my English.
App\Store
use Illuminate\Database\Eloquent\Model;
class Store extends Model
{
protected $fillable = ['name','location', 'price', 'open_time',
'closed_day'];
protected $table = 'stores';
public function photos(){
return $this->hasMany(StorePhoto::class);
}
public function categories(){
return $this->belongsToMany(Category::class,'category_store','category_id','store_id');
}
public function tags(){
return $this->belongsToMany(Tag::class, 'store_tag', 'tag_id', 'store_id');
}
}
App\Category
protected $fillable = ['store_id', 'category_id'];
public function stores()
{
return $this->belongsToMany(Store::class,'category_store','store_id','category_id');
}
App\Tag
protected $fillable = ['store_id', 'tag_id'];
public function stores()
{
return $this->belongsToMany(Store::class, 'store_tag', 'store_id', 'tag_id');
}
Resource/Category
class Category extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'store' => $this->stores,
];
}
}
web.php
use App\Category;
use App\Http\Resources\Category as CategoryResource;
Route::get("/store/api/category", function (Request $request) {
$search_category = $request->get('category_id');
return new CategoryResource(Category::find($search_category));
});
You can use dot notation to eager load nested relations:
$category = Category::with('stores.tags')->find($request->get('category_id'));
The tags will then be accessible on each Store model related to the Category:
// create a single flattened array of all the tags
$tags = $category->stores->flatMap->tags;

How can I get all the users that has commented a post?

I'm working with Laravel 5 and I've the following Models
PostComment.php
class PostComment extends Model
{
protected $fillable = [
'post_group_id', 'user_id', 'comment_content'
];
public function post(){
return $this->belongsTo('App\PostGroup');
}
public function user(){
return $this->belongsTo('App\User');
}
}
PostGroup.php
class PostGroup extends Model
{
protected $fillable = [
'group_id', 'user_id', 'post_content'
];
public function user(){
return $this->belongsTo('App\User');
}
public function group(){
return $this->belongsTo('App\Group');
}
public function commented(){
return $this->hasMany(
'App\PostComment'
);
}
}
Group.php
class Group extends Model
{
protected $fillable = ([
'id'
]);
public function users(){
return $this->belongsToMany(
'App\User',
'user_group'
);
}
public function members(){
return $this->belongsToMany(
'App\User',
'user_group'
)->wherePivot('state','accepted');
}
public function posted(){
return $this->hasMany(
'App\PostGroup'
);
}
}
My web application presents groups, in which you can create posts and in which post you can write comments. In my database I've the following relationships:
Group: (id, name, description);
PostGroup: (id, group_id, user_id, post_content);
PostComment: (id, post_group_id, user_id, comment_content);
What I want to do is to create a collection of User objects, and then make a query to get all users, subscribed to a group, who have commented on a certain post, in MySQL looks like:
select users.* from users, post_comments where users.id = post_comments.user_id and post_comments.post_group_id="1"
So in my controller I've the following code
$theGroup = Group::find($groupId);
$thePost = PostGroup::find($postId);
$memberList = User::where('id', '<>', Auth::user()->id)->whereIn('id', $theGroup->users->pluck('id'))->
So, what I want to do is to extend that query to get the desidered result with ->get()->sortBy('last_name');, how can I exted it after the whereIn?
EDIT
User.php
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token','created_at','updated_at'
];
public function groups(){
return $this->belongsToMany('App\Group','user_group');
}
public function groupsAsAdmin(){
return $this->belongsToMany('App\Group','user_group')->wherePivot('role','admin');
}
public function groupsAsMember(){
return $this->belongsToMany('App\Group','user_group')->wherePivot('state','accepted');
}
public function groupsAsInvited(){
return $this->belongsToMany('App\Group','user_group')->wherePivot('state','pending');
}
public function posted(){
return $this->hasMany('App\PostGroup');
}
public function commented(){
return $this->hasMany('App\PostComment');
}
}
From your description, you already come up with a list of Users in advance, so that you only will find Posts with a Comment of these specific users.
Basically, what you want is to use whereHas($relation, $calback) to perform the checks you described:
$userIds = [2, 3, 5, 7, 11, 13, 17]; // or query them...
$postId = 123; // the id of the post where we want to look through the comments
User::where('id', '<>', Auth::id())
->whereIn('id', $userIds)
->whereHas('comments', function ($query) use ($postId) {
$query->where('post_group_id', $postId);
})
->get();
This will simply check if a user has written a Comment for the given post. Because you forgot to post your User model, I assumed that there is a relation available for the comments of the user.
You could also combine the first two conditions (user in list, but not the authenticated one) into one, if you want. $userIds = array_diff($userId, [Auth::id()]) does the job. where('id', '<>', Auth::id()) can be dropped from the query then.
If you do also need to check for an active subscription of the user to a group, it will be slightly more complex. But as you commented, you are already finding only users for a group, so this should be fine.
In PostComment, try this
$this->selectRaw(‘user_id, comment_content’)->where(‘post_group_id’, 1)->groupBy(‘user_id’)->get();

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 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