Laravel return relationship data based on locale - php

I have posts table that has related table where I store different translations based on post_id now when I want to return translation data based on user selected locale it says:
mb_strpos(): Argument #1 ($haystack) must be of type string, Closure given
Here is my function
$posts = Post::with('translations', function($q) {
$q->where('translate_code', app()->getLocale());
})->get();
dd($posts); // returning error above
But if I do this
$posts = Post::with('translations')->get();
dd($posts);
I will get following results
Here is translations data details:
My question is:
How can I return the one translation that has current locale name only?

If you using callback in with then use array of relations like below. Older version of laravel was working which you mentioned but latest version need array of relations when using callback.
$posts = Post::with(['translations'=> function($q) {
$q->where('translate_code', app()->getLocale());
}])->get();

using conditional eager loading should be like this:
$posts = Post::with(['translations'=> function($q) {
$q->where('translate_code', app()->getLocale());
}])->get();
while the relation name is the key, a closer to get data should be the value for the associative array for 'with' statement.

You can query your relation by using whereHas().
Docs: Laravel Docs Relationships
For example:
$posts = Post::whereHas('translations', function ($query) {
$query->where('translate_code', 'en');
})->get();
Maybe try to put the app()->getLocale() into a variable first. (after trying this out in tinker, this does seem te return a string, so may passing it by reference might help).

Related

Search many level Eloquent Collection

If I have a collection with many levels, are there any tricks to find out what I need to put in my where() to be able to search by it? This is what I have so far, but I get an empty array from it. $contacts->where('contacts.tags.id', $tag->id) I've also tried contacts.tags.tags.id This is what I get if I run dd($contacts)
You may be looking for Eloquent - Eager Loading With Constraints.
$id = 'Your ID you are searching for';
$contacts= App\Models\Contact::with(['tags' => function ($query) {
$query->where('id', '=', $id');
}])->get();
show me all the contacts where tags = id. if it's only one you may switch ->get() for ->first() to return the object instead of a collection (array)

Laravel Pagination with Get request

I've followed the instructions on the Laravel documentation for pagination with appends([]) however I'm having a little trouble with the persistence of these parameters.
Say for example, I pass home?category=Cars&make=Tesla to my view. What is the best way to paginate with them Get requests?
Right now I've passed the category as a parameter to the view as (where category is the model i've grabbed findOrFail with the request('category');)
$category_name = $category_model->name;
And then in my view it's like so:
{{ $vehicles->appends(['category' => $category_name])->links() }}
But when I go between pages in the pagination, this $category_name value doesn't seem to persist. Whats the recommended way to achieve what I want?
Thanks.
You can append the query string in your controller when you paginate the result. I'm not sure if that was your only question or even regarding applying the query string as a condition. So here is a sample showing you how to do both. This should give you an idea of how to do it. I just assumed the column names in this example.
$category = request('category');
$make = request('make');
$vehicles = Vehicle::when($category, function ($query) use ($category) {
return $query->where('category', $category);
})
->when($make, function ($query) use ($make) {
return $query->where('make', $make);
})
->paginate(10);
$vehicles->appends(request()->query());
return view('someview', compact('vehicles'));

How to check the collection having a relation in laravel?

We already know,
check the data type is that an array can use the php is_array to get the answer,
but, how we check a Collection that have a relation (hasMany)?
here is the code:
1:
User::where('name','alex')->first();
2:
User::where('name','alex')
->with(['article' => function($q){
$q->where('active', 1);
}])->first();
A function need to accept those kind data to do somthing,
and I need to know which one have a relation
I think you are referring to getRelations() method:
$user = User::where('name', 'alex')->first();
// If user has some relations loaded (obviously not here)
if ($user->getRelations()) {
}

Laravel fetch data from model where the condtions is from another model

I have a table called List which i planned to be displayed into view with this command : $lists= List::with('user', 'product.photodb', 'tagCloud.tagDetail')->get();. But, i want the data displayed is only those that has TagID equal to the one user inputted. Those data can be retrieved from TagCloud table.
What i am currently doing is :
$clouds = TagCloud::select('contentID')
->where('tagDetailID', '=', $tagID)
->get();
$lists = List::with('user', 'product.photodb', 'tagCloud.tagDetail')
->where('id', '=', $clouds->contentID)
->get();
But when i tried to run it, it only return a null value, even though when i am doing return $clouds, it does returned the desired ID.
Where did i do wrong ? Any help is appreciated !
A couple of gotchas with your current solution.
Using get() returns an Illuminate\Database\Eloquent\Collection object. Hence you can't use $clouds->contentID directly since $clouds is a collection (or array if you prefer). See Collection Documentation.
where(...) expects the third parameter to be a string or integer, aka single value. Instead, you are passing a collection, which won't work.
The correct way is to use whereHas() which allows you to filter through an eager loaded relationship.
Final Code:
$lists = List::with('user', 'product.photodb', 'tagCloud.tagDetail')
->whereHas('tagCloud',function($query) use ($tagID) {
return $query->where('contentID','=',$tagID);
})
->get();
See WhereHas Documentation.
What you want is whereHas()
$list = List::with(...)
->whereHas('relation', function($q) use($id) {
return $q->where('id', $id);
})->get();
Apply Where condition in you tagCloud model method tagDetail
public function tagDetail(){
return $q->where('id', $id);
}

Searching API with query string

I am currently building an API, I want to be able to search the API via the query string. So for example http://api.dev/?q=12
I can get the value entered but how do I then use this to search the database?
if ($q = Input::get('q'))
{
return( ModelName::where('id', '=', $q));
}
This doesn't seem to change the search and the same data is just returned.
ID's are unique so it doesn't surprise me you're getting the same result.
For Laravel I find the query builder to be better at handling search queries instead of Eloquent.
E.g.
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
Hope this helps.
To search from the db with Eloquent you can use both this ways:
ModelName::where('id', '=', $q)->get();
or
ModelName::find($q);
In the second example Laravel assumes that your Primary Key is id, so in case you have another field as your primary you have to overwrite it, by setting the property in the model.
class ModelName
{
...your props
private $primaryKey = 'yourPrimaryKey'
...
}

Categories