I want to fetch unique value for filters of all products.
My db structure as follows
id Product category_id format attribute
1 demo1 5 HD test1
2 demmo2 4 SD test3
3 demmo3 4 HD test2
4 demmo4 3 HD test3
I want add filters of format and attribute in product page. But in that HD comming 3 times. I want to display that one only.
I am not getting how to display only single time.
Below is my controller code:
$item = Item::where('active_status', 1)->where('status', "1");
$data['item_count'] = $item;
$data['item'] = $item->paginate(20);
return view('frontend.pages.explore', compact('data'));
Below is blade file
<div class="filter-btn">
#foreach($data['item'] as $resolution)
<a class="btn btn-white-outline display-4" href="">{{array_unique($resolution->format)}}</a>
#endforeach
</div>
I am not getting how to display unique value only. Anyone have idea then let me know
since you are paginating your data, your "first page" might not have all the formats, so you have to do another query to your database:
$formats = DB::table('items')->select('format')->distinct()->get()
...
view(..., compact('data', 'formats'))
in the blade table:
#foreach($formats as $resolution)
<a class="btn btn-white-outline display-4" href="">{{$resolution->format}}</a>
#endforeach
If I am correct about your query, then you need to use groupby to list the items in your controller.
$items = Item::groupBy('format')->get();
The solution would be to create a sperate model for Formatand relationship between it and Product or whatever model that needs format , then fetch formats from its table and apply eager load .
this may look longer than your solution , but this is standards shoiuld be taken for vrious reasons :
less sql queries
more flexibility and options regarding our new table
better and less code to crud format
single source for change
less database data and faster load
...
Product.php
public function format(){
return $this->belongsTo(Format::class);
}
Format.php
public function products(){
return $this->hasMany(Product::class);
}
Usage
in controller
// get all formts eager loaded with products
$formats = Format::with('products')->get();
//get all products
$product = Format::latest()->paginate(20);
return view('frontend.pages.explore', compact( 'products' ,'formats'));
in your view
// all prodcuts
#foreach($formats as $format)
<a class="btn btn-white-outline display-4" href="">{{$format->name}}</a>
#endforeach
// in filter ( at clicking ) no additional query
#foreach($format->products as $product)
...
#endforeach
Related
I have a datatable that fetches orders and is working and displaying properly. I show the orders to the users that initiated them. Then they can only search on their owns orders. Now I need to display a message to a user, if an order was found but it was initiated by another user, instead of displaying an empty result in the datatable. This will happen after typing in the search box and not when loading the datatable in the beggining. The problem is that the query already filters the results by user id so I cannot change it during manual search.
I can display code if needed but the function is quite big and I don't really need code but the logic/way of doing that.
Do you have any suggestions on how I could accomplish this?
Well, maybe not the best way to do it but that's how I solved it:
In the controller, I check for the search field, and run a query on the relationship but only on the orders that have different seller than the logged in user:
$otherSeller = "";
if(!empty($request->search['value']))
{
$ordersOtherSeller = Order::where('status_id', "!=", 3)->where('seller_id', '!=', $loggedUser->id)->whereHas('user', function ($q) use ($request){
$q->searchFullName($request->search['value']);
})->first();
if($ordersOtherSeller != NULL && $ordersOtherSeller->count() > 0)
$otherSeller = $ordersOtherSeller->user->full_name . ' ' . $ordersOtherSeller->seller->full_name;
}
And I set a custom variable with the table's json:
...
->with('otherSeller', $otherSeller)
->make(true);
Then on the datatable jquery drawCallBack, I check for a populated string that guarantees that the result is not returned by a query from the current user:
fnDrawCallback: function( oSettings ) {
var api = this.api();
if(api.ajax.json().otherSeller != "")
{
$('#alert-info span').text(api.ajax.json().otherSeller);
$('#alert-info').show();
}
else
$('#alert-info').hide();
},
And last is the toggling of the materialert element with updated text:
<div id="alert-info" class="materialert info" style="display: none;">
<i class="material-icons">info</i> <span></span>
<button type="button" class="close-alert">×</button>
</div>
I have estate_object table which holds information about estate, for example: address, city, region etc.
Then i have a seperate tables which holds just specific property of an object, for example on of the tables is objects_near.
I made seperate tables for that because each of those models can hold multiple values(they are checkboxes)for example objects_near cant hold values like - parking, airport, see, store etc.
So to escape unnecessary columns and null fields in estate_object table i made polymorphic many to many relationship between estate_objects table and tables which hold properties.
In my view i want to make a filter and querying things from estate_object table works fine. To filter properties which belong to one or more estate objects i have checkboxes. For example to query objects near estate i have checkboxes with multiple options. I can't figure out and can't find solution as well on how to query objects_near properties which are related just to specific estate_object.
This is how my checkboxe looks like:
<div class="form-group align-items-center">
<label class="col-form-label text-md-right">{{ trans('admin.estate-obj.label.columns.objects_near') }}
</label><br>
#foreach($estate_objects_near as $objects_near)
<input type="checkbox" id="{{ $objects_near->name }}" name="objects_near[]" value="{{
$objects_near->id }}">
<label for="{{ $objects_near->name }}">{{ $objects_near->name }} </label>
#endforeach
/div>
Estate_object_near model:
public function estateObj()
{
return $this->morphToMany(EstateObj::class, 'estateable');
}
EstateObj model:
public function objectsNear()
{
return $this->morphedByMany(Estate_objects_near::class, 'estateable');
}
EstateObjController:
function( $query) use ($request) {
if($request->has('address')){
$query->where('address', $request->address);
}
if($request->has('price')){
$query->whereBetween('price', [$request->price['min'], $request->price['max']]);
}
if($request->has('room_qty') ){
$query->where('room_qty', $request->room_qty);
}
// trying to access properties which are selected in checkbox and related to estate
object
if($request->has('objects_near')){
$objNear = Estate_objects_near::find(1);
$obj = $objNear->estateObj;
$query->where($obj, $request->objects_near);
}
});
If i dump out $obj i am getting relations with pivot table 'estateable' and i can see which property is related with specific estate obj, but when i try to execute it shows me SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters.
I have tried to use whereHas function as well, but then i get this error - Argument 1 passed to Illuminate\Database\Eloquent must be an instance.
Have tried whereHasMorph as well:
$query->whereHasMorph('estateable', [Estate_objects_near::class], function ($query) {
$query->where('id', $request->objects_near);
})->get();
This leads to 'Call to undefined method App\Models\EstateObj::estateable()'
Would appreciate suggestions very much.
Following query worked for me:
if($request->has('objects_near')){
$query->whereHas('objectsNear', function ($query) use ($request) {
$query->whereIn('estate_objects_near.id', [$request->get('objects_near')]);
})->get();
}
As it turned out whereHasMorph works just with morphTo relations.
If anybody has the same problem and would like to know more of my code structure let me know.
Good day, i have a laravel 5.8 project and i'm having a little problem
i have this code
public function doctor_details($doctor_id){
$doctor = DB::table('doctors')->select('specification')->where('doctor_id', $doctor_id)->get>first();
$specs_data = explode(',', $doctor_specs);
$specs_array = [];
foreach ($specs_data as $doctor_spec) {
$doctor_spec_result = DB::table('specializations')->where { return explode('speciality_id'',', $doctor_spec)->get();
foreach ($doctor_spec_result as $doctor_spec_res) {
$specs_array[] = $doctor_spec_res->speciality_name;
}
}
return view ('doctor_details', compact('doctor', 'specs_array'));
}
now if i do dd($doctor_spec_result); the result is
as you can see i'm getting an empty array but if i do dd($specs_data); the result is
as you can see there's definitely a data but i can't make it work
this is my blade
<div class="row">
<div class="col-lg-12">
<h3>{{ $doctor->doctor_name }}</h3>
</div>
<div class="col-lg-12">
#foreach( $specs_array as $spec_output )
<p>{!! $spec_output !!}</p>
#endforeach
</div>
</div>
I think you are trying to get an list only containing the values of the specification field for the particular rows queried, so that you can then get the specialty_names. You can use the pluck method on the builder to do this for you. If a search by doctor_id could return more than one result:
$doctor_specs = DB::table('doctors')
->where('doctor_id', $doctor_id)
->pluck('specification')
->transform(function ($item) { return explode(',', $item); })
->flatten();
$specs_array = DB::table('specializations')
// use whereIn to find all the rows by 'specialty_id'
->whereIn('speciality_id', $doctor_specs)
->pluck('specialty_name')
->toArray();
return view ('doctor_details', compact('doctor', 'specs_array'));
Laravel 6.x Docs - Database - Query Builder - Retrieving Results pluck
Laravel 6.x Docs - Collections - Methods - transform
Laravel 6.x Docs - Collections - Methods - flatten
Update:
Though since doctor_id is a key there will only be one, we can remove the collection methods and deal with this simpler:
$doctor_specs = explode(
',',
DB::table('doctors')->where('doctor_id', $doctor_id)
->value('specification')
);
Ideally:
Or if $doctor was retrieved with all columns from the doctors table, including specification:
$doctor_specs = explode(',', $doctor->specification);
You can simplify your code using join
$doctor_spec_result = DB::table('doctors')
->select('specializations.speciality_name')
->join('specializations','specializations.speciality_id','doctors.specification')
->where('doctors.doctor_id', $doctor_id)
->get();
return view ('doctor_details', compact('doctor', 'doctor_spec_result '));
Change in this line.
$doctor_spec_result = DB::table('specializations')->where('speciality_id', $doctor_spec)->get();
you are checking the worng attribute. As you are getting specification in 0 index.
speciality_id to specification
How to show TeamController#index and ProductController#index both show list of team and product inside one view main.blade.php
Looks like you want to show two datasets on one page. Basically, it means you have to execute two controller methods but it's not necessary to follow each and everything that official documentation says.
For example, if Products belong to a team, you can execute only TeamController#index and show products as given below.
#foreach($teams as $team)
#foreach($team->products as $product)
{{ $product->name }}
#endforeach
#endforeach
If no teams and products are two different entities and does not have any relation, you can just pass teams and products like this:
TeamController.php
public function index()
{
$teams = Team::all();
$products = Product::all(); // Don't forget to include 'use App\Product'
return view('index',compact(['teams','products']);
}
and then you can show teams and products like this:
index.blade.php
#foreach($teams as $team)
{{ $team->name }}
#endforeach
#foreach($products as $product)
{{ $product->name }}
#endforeach
Getting information from two different models does not mean you have to execute two different controller functions.
Still, if you want to get data from two different controllers, you can setup index.blade.php and create two ajax requests that will get data from two different URLs (two different controller methods).
Let me know if you have any more questions.
You can't show results from two controllers like that. Create a view that includes both the view that TeamController#index and ProductController#index return. be aware that both might be extending a layout which will probably try to load your page twice, so keep in mind to split the views into smaller components and include only those.
More info here
https://laravel.com/docs/5.6/views#creating-views
Now I am developing a web application which enable to make a recipe by selecting multiple foods retrieved from mysql and inputting its amount. My user interface is like this;
Html
<form action="{{ URL::route('store') }}" method="post">
Your recipe name: <input type="text" name="recipe_name">
<!-- Generating multiple rows with jquery-->
'<tr>
<td>' + add_food + '<input name="food[]" hidden="true" value="'+ add_food +'"></td>
<td><input name="amount[]" class="amount" type="number"/></td>
</tr>'
<input type="submit" value="Make a recipe!">
</form>
Models and relation
I have already set up two table called Dish and Food which has many-to-many relation and these tables are intermediated by pivot table called dish_food.
What I want to do
I want to create new recipe called 'Pizza' which consists from 80g of bread, 20g of cheese and 10g of sausage. So in my UI I select these three foods and input its amounts, then submit these data. Finally I want to insert dish_id, food_id, amount like this;
dish_id| food_id| amount
-------|--------|--------
1 | 1 | 80
1 | 2 | 20
1 | 3 | 10
Controller I am struggling now
public function store()
{
// Here comes some validation...
// Getting data from UI.
$name = Input::get('name');
$foods = Input::get('foods'); // $foods is storing multiple data.
$amounts = Input::get('amount'); // $amounts is storing multiple data.
// Store recipe name into Dish table.
$dish = Dish::create([
'name' => $name
]);
// Here is my problem.
$food_ids = Food::where('name', '=', $foods)->get(['id']);
foreach($food_ids as $position => $food_id){
$dish->foods()->attach($food_id, array_get($amounts, $position));
return Redirect::route('create-recipe')
->with('global', 'You have made one recipe!');
}
Problem
With the code above, I could insert a new recipe name into Dish table like this;
dish_id| name
-------|--------
1 | pizza
But I can't insert multiple data into my pivot table dish_food, and I can not get any error message! So I need YOUR help. HOW TO FIX MY CODE?
I already checked related question like this;
Laravel attach pivot to table with multiple values
Maybe you are getting just one id in this line
$food_ids = Food::where('name', '=', $foods)->get(['id']);
Try to change it to
$food_ids = Food::whereIn('name', $foods)->get(['id']);