Laravel Inertia prop not passing values - laravel

When calling an edit function the prop mealService is passing null values and will not populate form fields with values. It looks like the controller isn't loading the model to query the single record. The Create and Store functions work fine.
First time posting. And very new to coding. Please let me know if more info is needed for the question.
edit.vue
export default {
components: {
Head,
Link,
LoadingButton,
SelectInput,
TrashedMessage,
},
layout: Layout,
props: {
mealService: Object,
sites: Array,
},
remember: 'form',
data() {
return {
form: this.$inertia.form({
site_id: this.mealService.site_id,
meal_type: this.mealService.meal_type,
adults: this.mealService.adults,
tally: this.mealService.tally,
}),
}
},
MealServiceController
public function edit(MealService $meal_service)
{
return Inertia::render('MealServices/Edit', [
'mealService' => [
'id' => $meal_service->id,
'site_id' => $meal_service->site_id,
'meal_type' => $meal_service->meal_type,
'adults' => $meal_service->adults,
'tally' => $meal_service->tally,
],
'sites' => Auth::user()->sfa
->sites()
->orderBy('name')
->get()
->map
->only('id', 'name'),
]);
}
MealService Model
class MealService extends Model
{
use HasFactory;
use SoftDeletes;
public function resolveRouteBinding($value, $field = null)
{
return $this->where($field ?? 'id', $value)->withTrashed()->firstOrFail();
}
public function site()
{
return $this->belongsTo(Site::class);
}
public function scopeFilter($query, array $filters)
{
$query->when($filters['search'] ?? null, function ($query, $search) {
$query->WhereHas('site', function ($query) use ($search) {
$query->where('name', 'like', '%'.$search.'%');
});
})->when($filters['trashed'] ?? null, function ($query, $trashed) {
if ($trashed === 'with') {
$query->withTrashed();
} elseif ($trashed === 'only') {
$query->onlyTrashed();
}
});
}
}
Route
Route::get('mealServices/{mealService}/edit', [MealServicesController::class, 'edit'])
->name('mealServices.edit')
->middleware('auth');

In your edit function you are using meal_service while in your route you use mealService
Try naming the one in the edit function mealService too

Related

Display content for user and for admin

I would like that normal users don't see the pictures with a status of 0 (not visible) only the visible ones (status 1) but that admins can see everything.
Is this kind of solution viable or is there something cleaner to do?
The gates/policies are not adapted for that, I don't see any other solution to my knowledge, that's why I come to you
Thanks in advance
public function show($name)
{
if(Auth::user()->isAdmin()) {
$model = cache()->remember('model_show'.$name, Config::get('cache.ttl'), function() use ($name) {
return Model::where('name', $name)->with('pictures')->first();
});
$pictures = $model->pictures()->latest()->paginate(18);
} else {
$model = cache()->remember('model_show'.$name, Config::get('cache.ttl'), function() use ($name) {
return Model::where('name', $name)->with('visible_pictures')->first();
});
$pictures = $model->visible_pictures()->latest()->paginate(18);
}
return view('model.model')->with(['model' => $model, 'pictures' => $pictures]);
}
You can clean it up by using when function in the query itself.
public function show($name)
{
$model = cache()->remember('model_show'.$name, Config::get('cache.ttl'), function() use ($name) {
return Model::where('name', $name)->when( Auth::user()->isAdmin() , function ($q)
{
return $q->with('pictures');
}, function ($q)
{
return $q->with('visible_pictures');
})->first();
});
$pictures = $model->pictures()->latest()->paginate(18);
return view('model.model')->with(['model' => $model, 'pictures' => $pictures]);
}
or we could also use arrow functions
public function show($name)
{
$model = cache()->remember('model_show'.$name, Config::get('cache.ttl'), function() use ($name) {
return Model::where('name', $name)->when( Auth::user()->isAdmin() ,
fn($q) => $q->with('pictures') ,
fn($q) => $q->with('visible_pictures')
)->first();
});
$pictures = $model->pictures()->latest()->paginate(18);
return view('model.model')->with(['model' => $model, 'pictures' => $pictures]);
}

How to stop records coming back if relationship doesn't exist (Laravel)

I'm trying to stop 'addons' coming back in the AddonGroup if it doesn't have a 'productAddon'.
Is there a way this can be achieved?
Current Code:
$addonGroups = AddonGroup::whereIn("id", $addonGroups)
->whereHas(['addons.productAddon' => function ($query) use ($customise) {
$query->where('product_reference', $customise->package_reference);
}])
->with('addons')
->with(['addons.productAddon' => function ($query) use ($customise) {
$query->where('product_reference', $customise->package_reference);
}])
->with('addons.removals')
->get()->each(function($addonGroup) {
foreach ($addonGroup->addons as $key => $value) {
if ($value["image_key"]) {
$value["image_key"] = env("AWS_UPLOADS_URL") . $value["image_key"];
}
}
});
'addons':
public function addons() {
return $this->hasMany("App\Addon", "addon_group_id", "id")->where('active', 1);
}
'productAddon':
public function productAddon() {
return $this->hasOne("App\ProductAddon", "addon_id", "id")->without('product');
}
Error with current solution:
Call to a member function getRelationExistenceQuery() on array
After a lot of coffee and running multiple tests, I have finally answered my own question and came up with this solution:
$addonGroups = AddonGroup::whereIn("id", $addonGroups)
->with(["addons" => function ($query) use ($customise) {
$query->whereHas("productAddon", function ($builder) use ($customise) {
$builder->where('product_reference', $customise->package_reference);
})
->with('productAddon', 'removals');
}])
->get();

how to current use data from one with to another with ? i want to display model raport from base on model siswa

how to current use data from one with to another with ? i want to display model raport from base on model siswa
public function getRekapPengetahuanSiswa($id_kelas, $id_relasi_pelajaran){
$siswa = Relasi_kelas_siswa::where('id_kelas', $id_kelas)
->with('siswa.id_user')
->with(['siswa.relasi_kelas' => function ($querys) use ($id_relasi_pelajaran) {
$id_siswa = $querys->get();
$querys->with(['kelas.relasi_pelajaran' => function ($query) use ($id_relasi_pelajaran, $id_siswa) {
$query->where('id', $id_relasi_pelajaran);
$query->with(['topik' => function ($query2) use ($id_siswa) {
$query2->with(['tugas' => function ($query3) use ($id_siswa) {
$query3->whereIn('id_sub_penilaian', Sub_penilaian::where('type', 'pengetahuan')->get('id'));
$query3->with(['raport' => function ($query4) use ($id_siswa) {
$query4->where('id_siswa', $id_siswa->last()->id);
}]);
}]);
$query2->with(['kuis' => function ($query5) {
$query5->whereIn('id_sub_penilaian', Sub_penilaian::where('type', 'pengetahuan')->get('id'));
$query5->with(['raport' => function ($query6) {
$query6->where('id_siswa', 1);
}]);
}]);
}]);
}]);
}])->get();
return response()->json($siswa);
}

Laravel / OctoberCMS frontend filter

I am using OctoberCMS and I have created a custom component. I am trying to create a frontend filter to filter Packages by the Tour they are assigned to.
This is what I have so far. The issue is that the code is looking for a tour field within the packages table rather than using the tour relationship. Does anyone have any ideas?
<?php namespace Jakefeeley\Sghsportingevents\Components;
use Cms\Classes\ComponentBase;
use JakeFeeley\SghSportingEvents\Models\Package;
use Illuminate\Support\Facades\Input;
class FilterPackages extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Filter Packages',
'description' => 'Displays filters for packages'
];
}
public function onRun() {
$this->packages = $this->filterPackages();
}
protected function filterPackages() {
$tour = Input::get('tour');
$query = Package::all();
if($tour){
$query = Package::where('tour', '=', $tour)->get();
}
return $query;
}
public $packages;
}
I really appreciate any help you can provide.
Try to query the relationship when the filter input is provided.
This is one way to do it;
public $packages;
protected $tourCode;
public function init()
{
$this->tourCode = trim(post('tour', '')); // or input()
$this->packages = $this->loadPackages();
}
private function loadPackages()
{
$query = PackagesModel::query();
// Run your query only when the input 'tour' is present.
// This assumes the 'tours' db table has a column named 'code'
$query->when(!empty($this->tourCode), function ($q){
return $q->whereHas('tour', function ($qq) {
$qq->whereCode($this->tourCode);
});
});
return $query->get();
}
If you need to support pagination, sorting and any additional filters you can just add their properties like above. e.g;
protected $sortOrder;
public function defineProperties(): array
{
return [
'sortOrder' => [
'title' => 'Sort by',
'type' => 'dropdown',
'default' => 'id asc',
'options' => [...], // allowed sorting options
],
];
}
public function init()
{
$filters = (array) post();
$this->tourCode = isset($filters['tour']) ? trim($filters['tour']) : '';
$this->sortOrder = isset($filters['sortOrder']) ? $filters['sortOrder'] : $this->property('sortOrder');
$this->packages = $this->loadPackages();
}
If you have a more complex situation like ajax filter forms or dynamic partials then you can organize it in a way to load the records on demand vs on every request.e.g;
public function onRun()
{
$this->packages = $this->loadPackages();
}
public function onFilter()
{
if (request()->ajax()) {
try {
return [
"#target-container" => $this->renderPartial("#packages",
[
'packages' => $this->loadPackages()
]
),
];
} catch (Exception $ex) {
throw $ex;
}
}
return false;
}
// call component-name::onFilter from your partials..
You are looking for the whereHas method. You can find about here in the docs. I am not sure what your input is getting. This will also return a collection and not singular record. Use ->first() instead of ->get() if you are only expecting one result.
$package = Package::whereHas('tour', function ($query) {
$query->where('id', $tour);
})->get();

Laravel paginate view don't see

I'm trying to do paginate in my view. I have reaaalyy alot of products, but I want only 12 per page. This is my controller:
public function index(Request $request)
{
$products = Product::paginate(12);
if ($request->has('colorValue')) {
$products->whereHas('productColors', function ($query) use ($request) {
$query->whereIn('id', $request->colorValue);
});
}
if ($request->has('heelValue')) {
$products->whereHas('productHeelTypes', function ($query) use ($request) {
$query->whereIn('id', $request->heelValue);
});
}
if ($request->has('materialValue')) {
$products->whereHas('productColors', function ($query) use ($request) {
$query->whereIn('id', $request->materialValue);
});
}
if ($request->has('maxPrice')) {
if($request->maxPrice > 0){
$products->where('sell_price_gross', '<=', $request->maxPrice);
}
}
$colors = ProductColor::all();
$heels = ProductHeelType::all();
$materials = ProductMaterial::all();
return view('product-list', ['products' => $products->get(), 'colors' => $colors, 'heels' => $heels, 'materials' => $materials]);
}
}
Now I'm trying to render it in my view:
<div class="paginate">
{{$products->render()}}
</div>
But I have error:
Type error: Too few arguments to function
Illuminate\Support\Collection::get(), 0 passed in /home/ania/Dokumenty/Projekty/viola-kiosk/vendor/laravel/framework/src/Illuminate/Pagination/AbstractPaginator.php on line 568 and at least 1 expected
What is wrong??
I think you can try this change your return view code like:
return view(
'product-list',
['products' => $products, 'colors' => $colors, 'heels' => $heels, 'materials' => $materials]
);

Resources