Where query on Eloquent All() - laravel-4

$table = ExampleTable::all();
$elem = $table->find(1);
While above works, receding does not:
$table = ExampleTable::all();
$elem = $table->where('id', 1)->first();
Is there a way to achieve latter other than DB::table?

where() isn't available in Laravel 4.2, you have to use filter():
$table->filter(function($value) {
return $value->id == 1;
});

Related

Laravel filter of multiple variables from multiple models

Goodmorning
I'm trying to make a filter with multiple variables for example I want to filter my products on category (for example 'fruit') and then I want to filter on tag (for example 'sale') so as a result I get all my fruits that are on sale. I managed to write seperate filters in laravel for both category and tag, but if I leave them both active in my productsController they go against eachother. I think I have to write one function with if/else-statement but I don't know where to start. Can somebody help me with this please?
These are my functions in my productsController:
public function productsPerTag($id){
$tags = Tag::all();
$products = Product::with(['category','tag','photo'])->where(['tag_id','category_id'] ,'=', $id)->get();
return view('admin.products.index',compact('products','tags'));
}
public function productsPerCategory($id){
$categories = Category::all(); //om het speciefieke id op te vangen heb ik alle categories nodig
$products = Product::with(['category','tag','photo'])->where('category_id', '=', $id)->get();
return view('admin.products.index',compact('products','categories'));
}
These are my routes in web.php. I guess this will also have to change:
Route::get('admin/products/tag/{id}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');
Route::get('admin/products/category/{id}','AdminProductsController#productsPerCategory')->name('admin.productsPerCategory');
For filter both
change your URL like
Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');
Make your function into the controller like
public function productsPerTag($tagId = null, $categoryId = null){
$tags = Tag::all();
$categories = Category::all();
$query = Product::with(['category','tag','photo']);
if ($tagId) {
$query->where(['tag_id'] ,'=', $tagId);
}
if ($tagId) {
$query->where(['category_id'] ,'=', $categoryId);
}
$products = $query->get();
return view('admin.products.index',compact('products','tags', 'categories'));
}
You are trying to filter in your query but you pass only 1 parameter to your controller, which is not working.
1) You need to add your filters as query params in the URL, so your url will look like:
admin/products/tag/1?category_id=2
Query parameters are NOT to be put in the web.php. You use them like above when you use the URL and are optional.
2) Change your controller to accept filters:
public function productsPerTag(Request $request)
{
$categoryId = $request->input('category_id', '');
$tags = Tag::all();
$products = Product::with(['category', 'tag', 'photo'])
->where('tag_id', '=', $request->route()->parameter('id'))
->when((! empty($categoryId)), function (Builder $q) use ($categoryId) {
return $q->where('category_id', '=', $categoryId);
})
->get();
return view('admin.products.index', compact('products', 'tags'));
}
Keep in mind that while {id} is a $request->route()->parameter('id')
the query parameters are handled as $request->input('category_id') to retrieve them in controller.
Hope It will give you all you expected outcome if any modification needed let me know:
public function productList($tag_id = null , $category_id = null){
$tags = Tag::all();
$categories = Category::all();
if($tag_id && $category_id) {
$products = Product::with(['category','tag','photo'])
->where('tag_id' , $tag_id)
->where('category_id' , $category_id)
->get();
} elseif($tag_id && !$category_id) {
$products = Product::with(['category','tag','photo'])
->where('tag_id' , $tag_id)
->get();
} elseif($category_id && !$tag_id) {
$products = Product::with(['category','tag','photo'])
->where('category_id' , $category_id)
->get();
} elseif(!$category_id && !$tag_id) {
$products = Product::with(['category','tag','photo'])
->get();
}
return view('admin.products.index',compact(['products','tags','products']));
}
Route:
Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');

Eloquent is setting a value to null

i'm having an error with Eloquent (and Many to Many relationship).
This is my code:
$user = new Users;
$rs = $user
->company()
->where('company_role.users_id', $request->session()->get('usrid'))
->where('code', $request->company)
->first();
The query that Eloquent perform is this one:
select `companies`.*, `company_role`.`users_id` as `pivot_users_id`, `company_role`.`companies_id` as `pivot_companies_id`, `company_role`.`role_name` as `pivot_role_name` from `companies` inner join `company_role` on `companies`.`id` = `company_role`.`companies_id` where `company_role`.`users_id` is null and `company_role`.`users_id` = 1 and `code` = 12345678901 limit 1)"
How is this possible? Do you guys have any idea?
This is my Users model:
class Users extends Model
{
//table associated with model
protected $table = 'users';
protected $primaryKey = 'id';
public function company(){
return $this->belongsToMany('App\Companies','company_role')->withPivot('role_name');
}
}
It was a rookie error
i just changed this:
$rs = $user->company()->where('company_role.users_id',$request->session()->get('usrid'))->where('code',$request->company)->first();
into this:
$rs = $user->find($request->session()->get('usrid'))->company()->where('piva',$request->company)->first();
and everything works as expected.
Thanks to everyone!
First, define the variables
$user_id = $request->session()->get('usrid');
$user = User::find($user_id);
Then, you need to find the user and the companies they are attached, and an individual company with the search params
$companies = $user->company()->get();
$company = $user->company()->where('code', $request->company)->first();

How to use transform in paginated collection in laravel

I want to use map or transform in paginated collection in laravel 5.5 but I am struggling it work
This is what I was trying to do but getCollection is not available in LengthAwarePaginator as what we used to do in previous laravel versions see: How to transform paginated collection
$query = User::filter($request->all()
->with('applications');
$users = $query->paginate(config('app.defaults.pageSize'))
->transform(function ($user, $key) {
$user['picture'] = $user->avatar;
return $user;
});
This is what I receive but there is no pagination details in my result
How can I return transformed collection with pagination details?
For Laraval >= 8.x: if you want to perform the transform() on the collection of the paginated query builder result instead of doing the pagination on the full collection, one can use the method through():
User::filter($request->all()
->with('applications')
->paginate(config('app.defaults.pageSize'))
// through() will call transform() on the $items in the pagination object
->through(function ($user, $key) {
$user['picture'] = $user->avatar;
return $user;
});
I have ended up building custom paginate function in AppServiceProvider
use Illuminate\Support\Collection;
In register of AppServiceProvider
Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page') {
$page = $page ?: \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPage($pageName);
return new \Illuminate\Pagination\LengthAwarePaginator(
$this->forPage($page, $perPage),
$total ?: $this->count(),
$perPage,
$page,
[
'path' => \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
]
);
});
You should paginate before retrieving the collection and transforming as follows:
$query = User::filter($request->all())->with('applications')->paginate(50);
$users = $query->getCollection()->transform(function ($user, $key) {
//your code here
});
dd($users);
It should give you your desired result.
Your problem is that you are printing the $users variable that hold the array of the users in the current page. To get the paginated list try to return/print $query instead.
So your code should be as following:
$query = User::filter($request->all()
->with('applications');
$users = $query->paginate(config('app.defaults.pageSize'))
->transform(function ($user, $key) {
$user['picture'] = $user->avatar;
return $user;
});
return response()->json($query);
Happy Coding!
You can use method setCollection from Paginator class:
https://laravel.com/api/8.x/Illuminate/Pagination/Paginator.html#method_setCollection
$messages = $chat->messages()->paginate(15);
$messages->setCollection($messages->getCollection()->transform(function($item){
$item->created = $item->created_at->formatLocalized('%d %B %Y %H:%M');
return $item;
}));

Laravel eloquent whereIn with one query

In laravel, I can use many where rules as an array a run one query to the database using laravel eloquent where method to get needed result.
Code:
$where = [];
$where[] = ['user_id', '!=', null];
$where[] = ['updated_at', '>=', date('Y-m-d H:i:s')];
if($request->searchTerm) {
$where[] = ['title', 'like', '%' . $request->searchTerm . '%'];
}
Model::where($where)->get();
Question part:
Now I need to use Laravel Eloquent method whereIn with array params to get needed result with one query.
I tried by looping method but with many queries to the database.
Code:
$model = new Model;
$whereIn = [];
$whereIn[] = ['date', '>=', Carbon::now()->subDays(10)];
$whereIn[] = ['user_role', 'candidate'];
if (!empty($scope) && is_array($scope)) {
$whereIn[] = ['user_id', $scope];
}
if(is_array($employment) && !empty($employment)) {
$whereIn[] = ['employment', $employment];
}
if(is_array($experience) && !empty($experience)) {
$whereIn[] = ['experience', $experience];
}
foreach ($whereIn as $v) {
$model = $model->whereIn($v[0], $v[1]);
}
dump($model->get());
First I tired $model->whereIn($whereIn)->get() but it's return error. It's possible get results with one query using whereIn without looping?
Note: My $whereIn array will be dynamic array!
whereIn is a query builder function so you can't use it on the model directly. Instead you should create a query builder instance. I also suggest you use when instead of the if statements:
$models = Model::when(!empty($scope) && is_array($scope), function ($query) use ($scope) {
$query->whereIn('user_id', $scope);
})->when(!empty($employment) && is_array($employment), function ($query) use ($employment) {
$query->whereIn('employment', $employment);
})->when(!empty($experience) && is_array($experience), function ($query) use ($experience) {
$query->whereIn('experience', $experience);
})->get();
dump($models);
when essentially runs the function when the first parameter is true. There's more detail in the documentation under conditional clauses.
Since your $whereIn variable is an array of arrays it will work like :
$model->whereIn($whereIn[0][0], $whereIn[0][1])->get();
If it just a simple array then you can use :
$model->whereIn($whereIn[0], $whereIn[1])->get();
Do in Eloquent
$model = Model::whereIn('id', array(1, 2, 3))->get();
Or using Query builder then :
$model = DB::table('table')->whereIn('id', array(1, 2, 3))->get();

Laravel Eloquent get() indexed by primary key id

I often find it very useful to index my results by the primary key id.
Example:
$out = [];
$users = User::where('created_at', '>=', '2015-01-01')->get();
foreach ($users as $user) {
$out[$user->id] = $user;
}
return $out;
Is there anyway to do this in one shot with Eloquent? It's not useful to use the 0...n index.
You can accomplish this by using getDictionary() on your collection.
Like so:
$users = User::where('created_at', '>=', '2015-01-01')->get()->getDictionary();
Note: in newer version of Laravel (5.2+), getDictionary() was removed; keyBy() can be used instead:
$users = User::where('created_at', '>=', '2015-01-01')->get()->keyBy('id');
I created my own solution by having a super Model that extends Eloquent.
Full solution:
https://gist.github.com/yadakhov/741173ae893c1042973b
/**
* Where In Hashed by primary key
*
* #param array $ids
* #return array
*/
public static function whereInHash(array $ids, $column = 'primaryKey')
{
$modelName = get_called_class();
$primaryKey = static::getPrimaryKey();
if ($column === 'primaryKey') {
$column = $primaryKey;
}
$rows = $modelName::whereIn($column, $ids)->get();
$out = [];
foreach ($rows as $row) {
$out[$row->$primaryKey] = $row;
}
return $out;
}
Not with eloquent but this is potentially nicer option than looping through all the results.
$users = Users::all();
return array_combine($users->modelKeys(), $users);
You can use keyBy()
$users = User::where('created_at', '>=', '2015-01-01')->get()->keyBy('id')->toArray();

Resources