I have this line of code which gets results from a database:
'clanMembers' => User::find(Auth::user() -> clan_id) -> where('clan_id', '=', Auth::user() -> clan_id) -> orderBy('username') -> get()
Currently it orders by the username. I wish to change this to order by the clan_rank field. This clan_rank field will only ever contain 3 different values. These are:
1. Owner
2. Admin
3. Member
I wish to have my results ordered with Owners first, then Admin, then members. How can I change my line of code to achieve these results?
You need to use orderByRaw:
instead of orderBy part you should use
orderByRaw("FIELD(clan_rank , 'Owner', 'Admin', 'Member') ASC");
Related
I'm building an API to return shops from a database in ascending order except that it should begin with all shops named swiva eg Swiva Electronics, Swiva Gas, Swiva Mall etc. then proceed to all the other shops in ascending order.
I have tried the following code
$shops=Shop::join('users','users.id','=','shops.owner_id')
->select('shops.id','shops.name','users.email','users.tel','users.estate','shops.logo')
->orderBy('shops.name')
->get()
->partition(function ($item) {
return $item->name != 'Swiva Electronics';
})->flatten();
but that is not doing what I want as
It is not beginning with the intended row rather it is ending with it.
It is only working with one row only, I do not know how to specify all the other rows
Note that the output of this query is being returned as a json as follows
if(!$shops->isEmpty()){
return response()->json([
'success'=>true,
'shops'=> $shops
]);
}else if($shops->isEmpty()){
return response()->json([
'success'=>false,
'message'=> 'There exists no subscribed shops from '
]);
}
How can I achieve the intended output either through formatting the JSON( Which I do not know how to do) or by using eloquent functions.
You can use the Field Function of MySQL to achieve this see: https://www.w3schools.com/sql/func_mysql_field.asp
$shops = Shop::join('users','users.id','=','shops.owner_id')
->select('shops.id', 'shops.name', 'users.email', 'users.tel', 'users.estate', 'shops.logo')
->orderByRaw("FIELD(shops.`name`, 'Swiva Electronics', 'Swiva Gas', 'Swiva Mall') DESC, shops.`name`")
->get()
As we can't add all names in FIELD options by default it will list all other names first Use DESC order to invert it will move those names first in results and then sort the all other shop names by adding simple ASC order by shop names.
there are 2 models. Customers & Locations.
In a location single page, it should now be possible to display all customers from the location and filter them according to customer attributes.
The problem here is that when you enter something in the search field, customers are no longer picked out specifically from the location, but from all customers that exist.
Filtering is possible on the overview page (where all customers are displayed). However, as soon as the query is added that it should be specifically for customers who own the location, it is no longer possible.
return \App\Models\Customer::with('locations')
->whereHas('locations', function($q)
{$q->where('locations.id', $this->location->id)
->Where('customers.name','like', '%'.$this->search.'%')
->orWhere('customers.domain','like', '%'.$this->search.'%')
->orWhere('customers.number','like', '%'.$this->search.'%')
->orWhere('customers.email','like', '%'.$this->search.'%'); })
->orderBy($this->sortField, $this->sortDirection)
->paginate($this->page_number);
Unfortunately, I am not sure how to build the query that requires the first whereHas (which is only to find customers from the locations) and then the other Where commands for the search field.
To filter by specific location and using the search value
return \App\Models\Customer::with('locations')
->whereHas('locations', function($q) {
$q->where('id', $this->location->id);
})
->where(function($q) {
$q->Where('name','like', '%'.$this->search.'%')
->orWhere('domain','like', '%'.$this->search.'%')
->orWhere('number','like', '%'.$this->search.'%')
->orWhere('email','like', '%'.$this->search.'%');
})
->orderBy($this->sortField, $this->sortDirection)
->paginate($this->page_number);
In my table I have:
PRODUCT
id_product
name
status
Where the status assumes the following values:
1 (Active)
2 (Inactive)
3 (Archived)
In the Product index view, I want the user to see certain statuses based on the permissions. Example:
Administrator sees records with statuses 1, 2, and 3.
Moderator views: 1 and 2
User views: 1
How can I do this? What alternatives do I have?
You could add conditions to your search model (I guess you have a ProductSearch.php file) so that results will be filtered based on user's role.
I've never used Yii's RBAC but I suppose you have a method to get user role, as described here: https://stackoverflow.com/a/25248246/4338862
So in your search model I would add, after grid filtering conditions, one or more conditions:
if($isUser) {
$query->andFilterWhere([
'status' => 1,
]);
}
elseif($isModerator) {
$query->andFilterWhere(['or',
['status' => 1],
['status' => 2]
]);
}
I can give you a more detailed answer if you need it.
I have Django models set up like below.
class Person:
first_name
last_name
# More_fields
class Service1:
person(fk=Person)
# Service1_specific_fields
class Service2:
person(fk=Person)
# Service2_specific_fields
class Service3:
person(fk=Person)
# Service3_specific_fields
# More_services
I'm trying to create an "advanced search" view that will allow users use checkboxes to query the Person model for records that have services matching the checked boxes.
E.g. If checkboxes for services 1, 2, and 3 are checked, results should only be of Persons that have all three services.
Currently it is set up to get all objects from all 3 services and compare them to one another. As expect, this is extremely slow.
What's a better approach for this?
What about:
( Person
.objects
.filter( service1__pk__isnull = False )
.filter( service2__pk__isnull = False )
. and so on
)
You can use Q() to combine just checked conditions.
I have a query to select all the rows from the hire table and display them in a random order.
DB::table('hire_bikes')->order_by(\DB::raw('RAND()'))->get();
I now want to be able to put
concat(SUBSTRING_INDEX(description, " ",25), "...") AS description
into the SELECT part of the query, so that I can select * from the table and a shortened description.
I know this is possible by running a raw query, but I was hoping to be able to do this using Fluent or at least partial Fluent (like above).
How can I do it?
You can actually use select AS without using DB::raw(). Just pass in an array into the select() method like so:
$event = Events::select(['name AS title', 'description AS content'])->first();
// Or just pass multiple parameters
$event = Events::select('name AS title', 'description AS Content');
$event->title;
$event->content;
I tested it.
Also, I'd suggest against using a DB:raw() query to perform a concatenation of your description field. If you're using an eloquent model, you can use accessors and mutators to perform this for you so if you ever need a limited description, you can simply output it in your view and not have to use the same query every time to get a limited description. For example:
class Book extends Eloquent
{
public function getLimitedDescriptionAttribute()
{
return str_limit($this->attributes['description'], $limit = 100, $end = '...');
}
}
In your view:
#foreach($books as $book)
{{ $book->limited_description }}
#endforeach
Example Output (not accurate to limit):
The description of this book is...
I'd also advise against using the DB facade because it always utilizes your default connection. If you're querying a secondary connection, it won't take this into account unless you actively specify it using:
DB::connection('secondary')->table('hire_bikes')->select(['name as title'])->get();
Just to note, if you use a select AS (name AS title) and you wish to update your the model, you will still have to set the proper attribute name that coincides with your database column.
For example, this will cause an exception because the title column does not exist in your database table:
$event = Events::select('name AS title')->first();
$event->title = 'New name';
$event->save(); // Generates exception, 'title' column does not exist.
You can do this by adding a DB::raw() to a select an array in your fluent query. I tested this locally and it works fine.
DB::table('hire_bikes')
->select(
array(
'title',
'url',
'image',
DB::raw('concat(SUBSTRING_INDEX(description, " ",25),"...") AS description'),
'category'
)
)
->order_by(\DB::raw('RAND()'))
->get();
select(array(DB::raw('latitude as lat'), DB::raw('longitude as lon')))