I would like to ask your help. I want to display data to table and group by ID that looks like this in laravel 5.
Article 1: good article
Comments: 1 - i love this article
2 - good one
Article 2: read this
Comments: 3 - waiting for more
here's my API to fetch to my table
$.get('/dev/api/getPODetails?id=' + id, function(data){
console.log(data);
$.each(data, function(index, getPODetails){
$('table.table tbody').append('<tr><td>PO#'+getPODetails.id+'</td><br><td>'+getPODetails.itemdesc+'</td><td>'+getPODetails.ordered+'</td></tr>');
})
});
and my controller
public function getPODetails(){
$supplierid = Input::get('id');
$getSupplierDetails = DB::table('purchase_headers')
->where('purchase_headers.partner_id',$supplierid)
->leftJoin('purchase_details', 'purchase_headers.id', '=', 'purchase_details.po_no_id' )
->leftJoin('items', 'purchase_details.item_id', '=', 'items.id' )
->select('items.description as itemdesc', 'purchase_details.qoh as ordered', 'purchase_headers.id as id')
->groupBy('purchase_details.id')
->get();
return Response::json($getSupplierDetails, 200, array(), JSON_PRETTY_PRINT);
}
And I want to save all the details from the table.
Related
I am using laravel eager loading to load data on the jquery datatables. My code looks like:
$columns = array(
0 => 'company_name',
1 => 'property_name',
2 => 'amenity_review',
3 => 'pricing_review',
4 => 'sqft_offset_review',
5 => 'created_at',
6 => 'last_uploaded_at'
);
$totalData = Property::count();
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$dir = $request->input('order.0.dir');
$query = Property::with(['company','notices']);
$company_search = $request->columns[0]['search']['value'];
if(!empty($company_search)){
$query->whereHas('company', function ($query) use($company_search) {
$query->where('name','like',$company_search.'%');
});
}
$property_search = $request->columns[1]['search']['value'];
if(!empty($property_search)){
$query->where('properties.property_name','like',$property_search.'%');
}
if(!Auth::user()->hasRole('superAdmin')) {
$query->where('company_id',Auth::user()->company_id);
}
$query->orderBy($order,$dir);
if($limit != '-1'){
$records = $query->offset($start)->limit($limit);
}
$records = $query->get();
With this method I received error: Column not found: 1054 Unknown column 'company_name' in 'order clause' .
Next, I tried with following order condition:
if($order == 'company_name'){
$query->orderBy('company.name',$dir);
}else{
$query->orderBy($order,$dir);
}
However, it also returns similar error: Column not found: 1054 Unknown column 'company.name' in 'order clause'
Next, I tried with whereHas condition:
if($order == 'company_name'){
$order = 'name';
$query->whereHas('company', function ($query) use($order,$dir) {
$query->orderBy($order,$dir);
});
}else{
$query->orderBy($order,$dir);
}
But, in this case also, same issue.
For other table, I have handled this type of situation using DB query, however, in this particular case I need the notices as the nested results because I have looped it on the frontend. So, I need to go through eloquent.
Also, I have seen other's answer where people have suggested to order directly in model like:
public function company()
{
return $this->belongsTo('App\Models\Company')->orderBy('name');
}
But, I don't want to order direclty on model because I don't want it to be ordered by name everytime. I want to leave it to default.
Also, on some other scenario, I saw people using join combining with, but I am not really impressed with using both join and with to load the same model.
What is the best way to solve my problem?
I have table like: companies: id, name, properties: id, property_name, company_id, notices: title, slug, body, property_id
The issue here is that the Property::with(['company','notices']); will not join the companies or notices tables, but only fetch the data and attach it to the resulting Collection. Therefore, neither of the tables are part of the SQL query issued and so you cannot order it by any field in those tables.
What Property::with(['company', 'notices'])->get() does is basically issue three queries (depending on your relation setup and scopes, it might be different queries):
SELECT * FROM properties ...
SELECT * FROM companies WHERE properties.id in (...)
SELECT * FROM notices WHERE properties.id in (...)
What you tried in the sample code above is to add an ORDER BY company_name or later an ORDER BY companies.name to the first query. The query scope knows no company_name column within the properties table of course and no companies table to look for the name column. company.name will not work either because there is no company table, and even if there was one, it would not have been joined in the first query either.
The best solution for you from my point of view would be to sort the result Collection instead of ordering via SQL by replacing $records = $query->get(); with $records = $query->get()->sortBy($order, $dir);, which is the most flexible way for your task.
For that to work, you would have to replace 'company_name' with 'company.name' in your $columns array.
The only other option I see is to ->join('companies', 'companies.id', 'properties.company_id'), which will join the companies table to the first query.
Putting it all together
So, given that the rest of your code works as it should, this should do it:
$columns = [
'company.name',
'property_name',
'amenity_review',
'pricing_review',
'sqft_offset_review',
'created_at',
'last_uploaded_at',
];
$totalData = Property::count();
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$dir = $request->input('order.0.dir');
$query = Property::with(['company', 'notices']);
$company_search = $request->columns[0]['search']['value'];
$property_search = $request->columns[1]['search']['value'];
if (!empty($company_search)) {
$query->whereHas(
'company', function ($query) use ($company_search) {
$query->where('name', 'like', $company_search . '%');
});
}
if (!empty($property_search)) {
$query->where('properties.property_name', 'like', $property_search . '%');
}
if (!Auth::user()->hasRole('superAdmin')) {
$query->where('company_id', Auth::user()->company_id);
}
if ($limit != '-1') {
$records = $query->offset($start)->limit($limit);
}
$records = $query->get()->sortBy($order, $dir);
Say I have 2 models, Category and POI where 1 Category can have many POIs.
$categoryDetails = Category::with([
'pois' => function ($query) {
$query->where('is_poi_enabled', true);
},
])->findOrFail($id);
The above query returns results from the specific Category as well as its POIs.
However, with the query below:
$query->select('id', 'name')->where('is_poi_enabled', true);
The POIs become empty in the collection.
Any idea why this is happening? When added a select clause to the Eloquent ORM?
While doing a select it's required to fetch the Relationship local or Primary key.
For an example POIs table contains category_id then it's required to select it
Try this:
$categoryDetails = Category::with([
'pois' => function ($query) {
$query->select(['id', 'category_id', 'is_poi_enabled'])
->where('is_poi_enabled', true);
},
])->findOrFail($id);
Good luck!
I have 2 tables Articles and Revisions
There is a relationship between them one2many
The Revisions table has 2 columns isApproved and isPublished
Now, I want to select all articles, when its first Approved revision is Published
Article::whereHas('revisions', function ($query) {
$query->where('isApproved', 1)->where('isPublished', 1);
});
But this code selected all articles that have approved and published revisions
Try filter the results:
$articles = Article::
whereHas('revisions', function ($query) {
$query->where('isApproved', 1)->where('isPublished', 1);
})
->get()
->filter(function ($article) {
return $article->revisions->first(function ($revision) {
return $revision->isApproved == true;
})
->isPublished == true;
});
I have the table followers, with:
id, user_id, follower_id, type
type = type of follow, if follow user = 0, page = 1, group = 1
I use the user_id to put the page_id and group_id too.
Now is the problem, I want to make different relations if type is different... If type = 0, will relate with users table and share table, if type = 1, will relate with pages table...
I'm try like this:
Model:
public function page_links()
{
return $this->hasMany(Link::class, 'page_id', 'user_id')->Select('links.id', 'links.title', 'links.photo', 'links.country', 'links.friendly_url', 'links.clicks', 'links.description', 'links.suggestions', 'links.count_comments', 'links.url', 'links.shares', 'links.page_id', 'links.tag_id', 'links.created_at')->where('sponsored', 0)->where('scheduled', 0)>where('status', 1)->take(3)->orderBy('id','desc');
}
public function user_links()
{
return $this->hasMany(Share::class, 'user_id', 'user_id')->Select('id', 'link_id', 'user_id', 'shared_in', 'content', 'created_at')->take(3)->orderBy('id', 'desc')->where('type', '=', 0);
}
public function scopeProfile($query) {
return $query
->when($this->type == 0, function($q){
return $q->with('user_links');
})
->when($this->type == 1, function($q){
return $q->with('page_links');
})
->when($this->type == 2, function($q){
return $q->with('group_links');
});
}
Controller:
$feed = Feed::Profile()->where('follower_id', auth()->user()->id)
->take(10)
->get();
But ALL, even the type 1 returns "user_links" relation. I don't know if the relation is correct...
Someone can help me?
Well, in my point of view, you should modify your migration.
Instead of have your table with :
id, user_id, follower_id, type
I'll do this :
id, user_id, page_id, group_id, follower_id, type
Don't do weird stuffs like that in your database, just add 2 fields and / or relations in your migration table. Set it to unsigned() AND nullable(), this way you'll be able to know quickly if there is a relation or not with each one of your page or group, and you won't have to make weird stuff to check for it :D
I have a database of fruit, and lets say I want all the red fruit from it:
$allfruit = DB::table('fruits')->Where("color","=","red")->paginate(10);
I also have a table of user's least favourite fruit. If a user is logged in I'm trying to pass their ID through to get a list of all their hated fruit:
$leastfav = DB::table('dislikes')->Where("userID","=",Auth::user()->id)->get();
Now what I'd like to do is remove all the entries from $allfruit that appear in the 'dislikes' table with that user's ID.
What I've tried is something like:
$allfruit = DB::table('fruits')->Where("color","=","red")->merge($leastfav)->where(fruits.ID,"!=", "dislikes.fruitID")->paginate(10);
My DB is SQLite if that helps. Thanks
You could use whereNotExists (the inverse of whereExists()):
$allfruitQuery = DB::table('fruits')->where('color', 'red');
if (auth()->check()) {
$allfruitQuery->whereNotExists(function ($query) {
$query->select(DB::raw(1))
->from('dislikes')
->where('userID', auth()->id())
->whereRaw('fruits.ID = dislikes.fruitID');
});
}
$allfuit = $allfruitQuery->paginate(10);
Alternatively, (if you're using 5.2+) you could use when():
$allfuit = DB::table('fruits')->where('color', 'red')
->when(auth()->check(), function ($query) {
$query->whereNotExists(function ($query) {
$query->select(DB::raw(1))
->from('dislikes')
->where('userID', auth()->id())
->whereRaw('fruits.ID = dislikes.fruitID');
});
})
->paginate(10);