I'm kinda stuck here, any help appreciated:
So I have a table with themes, and then sub-themes. Each theme has many sub-themes, and I want to be able to destroy a theme and all sub-themes goes along.
I did this with this controller:
public function destroy()
{
$comtheme = Theme::findOrFail(request('idDelTCom'));
$comtheme->delete();
$comfiles = Subtheme::where('comtheme_id', '=', request('idDelTCom'));
$comfiles->delete();
return back();
}
Which is working. My problem is the following:
Each Sub-theme has files associated. When I delete a single sub-theme, I can delete the file using:
unlink(storage_path('app/public/com/checklists/'.$file));
I've tried doing the same, and it won't work. I figure the problem is with my query, but I can't wrap around what I have to do here...
If I can't work this out I'll just prevent the deletion of a Theme until all sub-themes are deleted, but it would be better to just delete all.
Thanks in advance!
Use a on observer on your Theme model. There are many ways to implement this but I prefer to declare it in the model class itself, so in the class for the Theme model put this:
protected static function boot()
{
parent::boot();
static::observe(ThemeObserver::class);
}
Of course there would be a use statement pointing to your ThemeObserver class up top, place the class where ever you like in the project, with your model or a dedicated observer directory.
In the ThemeObserver class you'll want an event for deleting like this:
public function deleting(Theme $theme)
{
// delete subthemes here
}
You can set up a similar observer for your subthemes where you delete the files associated with them or just do it here.
https://laravel.com/docs/5.7/eloquent#observers
I figured it out. I know I might not have asked the question the right way, so thanks for the help anyway!
The problem was I was trying to delete several files, and my unlink code wasn't expecting a colletion or a builder obviously. I got it working like this:
public function destroy()
{
$comfiles= Comfile::where('comtheme_id', '=', request('idDelTCom'))->get();
foreach($comfiles as $comfile){
$file = $comfile->file_name;
unlink(storage_path('app/public/com/checklists/'.$file));
}
$comfileDel = Comfile::where('comtheme_id', '=', request('idDelTCom'));
$comfileDel->delete();
$comtheme= Comtheme::findOrFail(request('idDelTCom'));
$comtheme->delete();
return back();
}
So I get a collection of the data I want to delete, run a foreach loop to delete each file in there. Then I run a builder of the same data to delete it, and off we go.
Related
I'm trying to display the latest Topic that is related to a Theme. I did this before and I tried the following code in the ThemesController (Index method, Sinse it's the homepage),
$topics = Theme::with('topic', 'lastTopic.user')->get();
$themes = Theme::all();
return view('themes.index')->with('themes', $themes)->with('topics', $topics);
And the method I'm calling is this.
public function lastTopic()
{
return $this->hasOne(Topic::class)->latest();
}
The method sits inside the Theme Model, It doesn't matter if i put the method in the Topic Model of the Theme Model, It still gives me the same error. So what is causing this issue? This is for my homepage so the route is this Route::get('/', 'ThemesController#index')->name('home');. I know it is something I've done before but I can't figure it out. Thanks in advance
You should add a topic method in your Theme model (if you haven't already did).
Something like:
public function topic()
{
return $this->hasMany(Topic::class);
}
I used yii blog from Yii Framework
I want clear data from like table after delete post
I used This code at Post Model
protected function afterDelete()
{
parent::afterDelete();
Like::model()->deleteAll('post_id='.$this->id);
}
But Not Delete data from Like Table after delete post
I suggest you put your code in a beforeDelete, not afterDelete, I think it is better to first delete related data and then the main object.
I also suggest opening CActiveRecord class from YiiFramework and look how exactly are the methods defined, see if you are using the right (public/protected) and if you need to return a "true" or no need to return anything.
Here's a working example of beforeDelete:
protected function beforeDelete() {
if (parent::beforeDelete()) {
// requests
Yii::app()->db->createCommand("DELETE FROM x2_oirequest_city WHERE city_id={$this->id}")->execute();
return true;
}
}
I made a view composer in Laravel 5. When i use a wildcard *, to add something to all my views, it get's called at least twice. It runs when my master template is loaded, and again when my content page is included. This will give problems in the future, because it executes the query it does multiple times. I was able to fix the multiple querying by storing it in a static variable :
class StoreComposer {
static $composed;
public function __construct(StoreRepository $repository)
{
$this->store = $repository;
}
public function compose(View $view)
{
if(static::$composed)
{
return $view->with('store', static::$composed);
}
static::$composed = $this->store->pushCriteria( new WithCategories() )
->pushCriteria( new WithSettings() )
->applyCriteria()
->all();
$view->with('store', static::$composed);
}
}
My question is, is there a way to make sure it only runs once, no matter how many views i load, or is there another solution to this? The way i fixed it now doesn't feel right to me. Thanks!
Unfortunately no, there is no way to make it run once, due to the way View Composers are implemented. The Illuminate\View\View::renderContents() method is responsible for calling the composer bound to a view, and since any form of view rendering (Blade template inheritance or simple #include statements) executes that method, it means that when any view is rendered any composer bound to it gets triggered.
Since in your case you use a * wildcard to bind all views, if your page renders ten views, the composer will get executed ten times. However your approach looks like a good solution to solve this shortcoming.
You can use config here to resolve multiple times query run issue for example show below code.
public function compose(View $view)
{
if(!Config::has('composeVars'))
{
Config::set('composeVars') = [
'data' => User::all();
];
}
$view->with('*', Config::get('composeVars'));
}
Try this singleton solution or use cache https://laracasts.com/discuss/channels/laravel/executing-a-view-composer-only-once
On Laravel 5.6.38 works fine
I am trying to make commenting on my site modular, so I have attempted to use view::composer to run the queries that are required to populate the comment data whenever the comment view is called, then my plan was to include the comment view in any place i needed comments, and then connect it to the appropriate comment table in my database.
The functions I have made for commenting fit each of the comment tables I've created and I've made the view composer work, the only thing is now since the function to get all the comment data is being called by the view composer when the comment view is being set up, that function no longer has access to the id that was being passed to it ( normally it is in the route like: Route::get('/{id}', 'controller#method');).
I have been searching for hours trying to figure out how to pass the variable in, but with no luck.. Maybe I'm missing some really basic detail, Idk, but I can't figure it out and haven't found anything that solves the problem, please help..
It seems like it should be so simple, I've tried doing:
$var = Route::get('/{id}', function($id){ return $id; }
Which i thought might do it, but the result was an error saying whatever the response was couldn't be converted to string.
Option 1: Access the route parameter
View::composer('comment-view', function($view){
$id = Route::current()->getParameter('id');
});
Option 2: Use the view to access the id
In your controller: return View::make('view-name')->with('commentId', $id);
View::composer('comment-view', function($view){
$id = $view->commentId;
});
I want to cache a query in CodeIgniter. What I did for my test is make a controller, that I named show.php:
class Show extends CI_Controller{
public function __construct()
{
parent::__construct();
$this->load->model('rejaal_show');
}
public function _remap($method = '',$param = array())
{
$method = intval($method);
$this->output->cache(5);
var_dump ($this->rejaal_show->temp($method));
}
}
And a model that I named rejaal_show.php:
public function temp($id)
{
$this->db->cache_on();
$this->db->where('id',$id);
$query = $this->db->get('system_store_table');
return $query->result();
}
When I call http://localhost/rejaal/show/1 for the first time, it will show a result, but when I call it for the second time, it does not show anything.
I should delete the query cache file to show it again? How should I solve this problem?
With special thanks for your attention.
Can you confirm that you have set $db['default']['cachedir'] to the path of a writable folder in application/config/database.php and that when the query is first run it creates a cache file in there?
The only other reason I can think of for it failing is by your use of the _remap override. I have not used db caching using _remap, but know that CodeIgniter creates a folder called controller+action in your cache folder, and might not be handled very well if using remap? Someone correct me if I am wrong about this.
In the CodeIgniter User Guide page for Web Page Caching, it says:
Because of the way CodeIgniter stores content for output, caching will only work if you are generating display for your controller with a view.
Do your var_dump inside a view.