Laravel - updateOrCreate or a sync method? - laravel

I'm trying to see what my best route should be but for the sake of ease I will make this sound much simpler than it is.
I have two models, one called donor and one called donation. For the relationships, the donor has many donations.
In my edit form of the donor model, I have the ability to create, update or delete the donations from the same form.
Updating and creating are easy at the moment because I can use updateOrCreate. But what happens if I want to delete a donation?
Would I perform an actual query filtering out the ids of the donations that were still on the edit form (and therefore not deleted by the user) and then delete the models from there? Or is there a better way of handling this action?
Thanks in advance.

In your DonationController you could select the donations you want to delete with a query like this:
public function destroy($id)
{
$donation = Donation::where('donor_id','=', $id)->get();
$donation->delete();
}
In your view you could make a delete form and them send him to this function in the controller. I think the best way to do it is make a foreach and loop the donations from the donor inside.
#foreach($donor->donations as $donation)
{
<form method="POST" action="{{route('donor.destroy', $donation->id)}}">
<button type="submit">Delete {{$donation->id}}</button>
</form>
}
#endforeach

Related

how to display data based on specific id in laravel?

I am new to laravel. I want to send data as id of existing data. Id comes from products.blade I send via href tag as shown below to gallery page. I have tried to find a way through other sites but it still doesn't work
<a class="btn btn-success" href="/dashboard/galleries/{{ $product->id }}"><i class="ri-image-add-line text-white"></i></a>
then i create a route like this
Route::resource('/dashboard/galleries', DashboardGalleryController::class)->middleware('admin')->shallow();
in the controller gallery, I made like this
public function index($id)
{
$gallery = Gallery::where('products_id', $id)->get();
return view('dashboard.galleries.index', compact('gallery'));
}
then inside the gallery page, I want to display a table to add images based on that id.
dashboard/galleries/index.blade.php
<h1>{{ $gallery->id }}</h1>
should i add data inside foreach or outside?
A restful resource controller sets up some default routes for you and even names them.
and ur case the logic should be inside show() function not index()
check this issue it will help u same issue solved here

Backpack for Laravel: how to add 'delete' per-line button conditionally?

I've a parent model which can have n childs
So I want to show delete button ONLY if it has not children (hasMany relationship must return 0 records).
How can I show 'delete' link in each lines of a table (in the list operation), but ONLY if a condition is valid?
The easiest option I see is to use a custom view for the Delete button, instead of the one in the package. Depending on how wide you want this change to be made:
A. If you want to do that across all CRUDs - it's easy, just publish the view by running:
php artisan backpack:publish crud/buttons/delete
This will place the file in your resources/views/vendor/backpack/crud/buttons, for you to change however you like. Inside the delete button view you have the current entry available as $entry so you can do something like $entry->children()->count() if you want. Be mindful that this will be run ONCE PER LINE so if you show 50 lines in the table for example, you'd need to find a way to optimize this.
B. If you want to do that for just one CRUD (eg. do it for Categories but not for Products), then you can do the same thing (publish the button view), but rename the button to something different like delete_if_no_children.blade.php so that it doesn't get used automatically for all CRUDs. Then use it only inside the controllers you want, inside setupListOperation(), by removing the "stock" delete button and adding yours:
// using the Backpack array syntax
$this->crud->removeButton('delete');
$this->crud->addButton('line', 'delete', 'view', 'crud::buttons.delete_if_no_children', 'end');
// using the Backpack fluent syntax
CRUD::button('delete')->view('crud::buttons.delete_if_no_children');
Use
withCount('children')
Docs: withCount
Additionally you can wrap delete buttons with blade directive
#can('destroy', $model) disabled #endcan
Docs: #can
<?php
namespace App\Policies;
use App\Models\Model;
use App\Models\User;
class ModelPolicy
{
public function update(User $user, Model $model)
{
return $model->children_count === 0;
}
}
Docs: policy
A hasMany relationship will return an empty Collection when there are no associated records. You can then proceed to call isEmpty() on the collection to verify there are no child records (children).
Example in PHP:
$parents = Parent::with('children')->get();
And then in your template you can do:
#foreach($parents as $parent)
#if($parent->children->isEmpty())
<button>Delete</button>
#endif
#endforeach

Model validation on different request

I have several models all of which have a create page. When a model is created, I do not perform any validation. This is because I allow the user at any time to go back and add to things.
However, at some point, I provide a button to the user
<a href="{{ route('projects.push', $project->id) }}" class="btn btn-info pull-right" data-token="{{ csrf_token() }}">
Push
</a>
All of the models in question are related to the Project model. When they click the push button, I am going to send the Models to an external system. However, at this point I need to validate that the
models being sent have all the required data. I know about validation on a model, but this is when they are created. Is it possible to validate them on a completely different action?
Thanks
Of course it is possible. It would be smart to store your rules and/or messages inside you model as a static function. An example would be:
// Project model
public static function rules()
{
return [
'field1' => 'rules1..',
'field2' => 'rules2..'
];
}
Then you can retrieve your rules anywhere in your application:
Validator::make($fields, Project::rules());
One last thing. You said you validate your model when it already has been created. I don't know if putting the entire retrieved model variable instead of $fields will work. Example:
$project = Project::find($id);
// Try this
Validator::make($project, Model::rules());
// Otherwise try this
Validator::make($project->attributes, Model::rules());
Hope this helps :)

Most efficient way to get a specific model from a collection in BLADE in Laravel

Hi im developing a site using Laravel and have some site data id like to keep track of such as facebook url, instagram url, address, phone number, etc. This information for this model is stored as a name and value in the DB, so example name:facebook and value:[facebook url here]. I know that i can retrieve all the models and get a collection, pass it to my view and loop through them, but id like a little more control to get specific models to use it where i need them on specific parts of the page. This is what I currently have it:
I have a model SiteMeta which i pass an instance to my view:
$site_meta = new \App\SiteMeta();
return view($page_string)->with('site_meta',$site_meta);
And in my SiteMeta Model:
public static function get($name)
{
return SiteMeta::where('name', '=', $name)->firstOrFail();
}
And then in my view im getting my specific model by its name:
<a target="_blank" href="{{$site_meta::get('Facebook')->value}}">
<i class="fa fa-facebook-official data-icon" aria-hidden="true"></i>
</a>
So my question is, is this the most efficient way to do it? Im doing this in various places on the contact page to display information like phone number and address and other site information which i feel like is a bit overload as it make a request to the database each time im doing sitemeta::get('name');
Is there a better way to get a specific one from the collection in BLADE? Thanks
I would pass it as an array from your controller method:
$site_meta = \App\SiteMeta::lists('value', 'name');
return view($page_string, compact('site_meta');
On your blade template you could do this:
$site_meta['Facebook'];

Laravel5-update table-fill dropdown and display actual value

Being newer to Laravel 5, I am trying to update a table, then i show all fields into a form using blade. I am also able to populate the drop-down list (select) in order to show values from another table, but I can't make the drop-down to point to the value in the main table (the one am trying to update).
Controller side: I use $user to pass all user data to the view and $profiles to pass data to fill the drop-down
public function edit($id){
$user = User::find($id);
$profiles = \DB::table('profiles')->lists('desc_profile', >'id_profile');
return view('user.edit')->with('user', $user)->with('profiles', $profiles);
}
View Side:
<div class="col-xs-6">
{!!Form::select('profiles', $profiles)!!}
</div>
In addition, I can update all the fields in the table BUT the values from the drop-down ... So basically everything is working fine for show and update values except for the ones in the .... drop downs...
need help! THX a lot
You can pass an optional 3rd argument to the select method that specifies which option you want to have selected. In other words, you pass in the specific id_profile that you want selected.
<div class="col-xs-6">
{!!Form::select('profiles', $profiles, $user->id)!!}
</div>
I passed in the user id as the 3rd argument only because we have no idea how you are structuring your database, but you should adjust that to match what you need.

Resources