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);
}
Related
I have searched quite a bit but cannot get other solutions working for my error using pagination:
It errors on the line containing {{ $dishes->links }}
I am trying to paginate my dish.index page.
My DishController index function looks like so:
public function index()
{
$dishes = Dish::paginate(2);
return view('dishes.dish_index')->with('dishes', $dishes);
}
I have even attempted the method of following this gist however I don't think I understand enough about collections in order to remedy my issue.
I also attempted to use $dishes = Dish::all()->paginate(2); but that returns the same error.
I don't think it's directly related but I don't have a route setup with {page} either, currently I only have Route::resource('dish', DishController::class);. Seperate concern but possibly related?
Any help is appreciated!
Controller
public function index()
{
$dishes = Dish::paginate(2);
return view('dishes.dish_index', compact('dishes'));
}
View
{{ $dishes->links() }}
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.
I have function in ProductsController productsCount(). It give me amount of records in table.
public function productsCount() {
$productsAmount = $this->Products->find('all')->count();
$this->set(compact('productsAmount'));
$this->set('_serialize', ['productsAmount']);
}
I want to call this function in view of PageController. I want to simply show number of products in ctp file.
How can i do this?
You can use a view cell. These act as mini controllers that can be called into any view, regardless of controller.
Create src/View/Cell/productsCountCell.php and a template in src/Template/Cell/ProductsCount/display.ctp
In your src/View/Cell/productsCountCell.php
namespace App\View\Cell;
use Cake\View\Cell;
class productsCountCell extends Cell
{
public function display()
{
$this->loadModel('Products');
$productsAmount = $this->Products->find('all')->count();
$this->set(compact('productsAmount'));
$this->set('_serialize', ['productsAmount']);
}
}
In src/Template/Cell/ProductsCount/display.ctp lay it out how you want:
<div class="notification-icon">
There are <?= $productsAmount ?> products.
</div>
Now you can call the cell into any view like so:
$cell = $this->cell('productsCount');
I think it would make more sense to just find the product count in the PageController. So add something like $productsAmount = $this->Page->Products->find('all')->count(); in the view action of PageController, and set $productsAmount. If Page and Products aren't related, then you can keep the find call as is as long as you include a use for Products.
Also check this out for model naming conventions: http://book.cakephp.org/3.0/en/intro/conventions.html#model-and-database-conventions
Model names should be singular, so change Products to Product.
you can not call controller method from view page. you can create helper, which you can call from view page.
here you will get a proper documentation to creating helpers-
http://book.cakephp.org/3.0/en/views/helpers.html#creating-helpers
It just depend on the kind of call you're making because there are 3 cases for your issue..
1- If you're calling by a link to click you simply do:
<?= $this->Html->link(_('Product number'),['controller' =>'ProductsController', 'action' => 'productsCount']) ?>
The 2 other cases are whether you want to render the result straight in that same view, then there are some workaround to do.
1- first you will need to check what are the associations between the Page table and the product table and use BelongTo or hasMany option to bind them togheter for proper use.
2- If no association between the tables then you will nedd TableRegistry::get('Produts'); to pass data from a model to another, just like this way in the Pages controller:
public function initialize()
{
parent::initialize();
$this->Products = TableRegistry::get('Produts');
}
But i quite believe that the first option is more likely what you described.
Also you can define static method as below
public static function productsCount() {
return = $this->Products->find('all')->count();
}
And use self::productsCount() in other action.
This is useful only if you need to get count multiple time in controller. otherwise you can use it directly in action as below:
$this->Products->find('all')->count();
while working yesterday with codeIgniter I found some strange(I don't know what to call),maybe I don't know whether it is normal or not as am a rookie using this framework.Below is my controller class.
class Posts extends CI_Controller
{
public function __construct() {
parent::__construct();
$this->load->model( 'post' );
}
public function index() {
// echo "<pre>";
// print_r($data['posts']);
// echo "</pre>";
$data['posts']=$this->post->get_posts();
$this->load->view( 'post_index', $data );
}
public function post( $postID ) {
$data['post']=$this->post->get_post_by_ID( $postID );
$this->load->view( 'post', $data, FALSE );
}
I found that strange in function "post" the reason is simple if I change the function name then I will get the error-page not found.
Why is that?? Is it necessary to have function name and view name to be same.As I told am a beginner to this framework.So please co-operate and provide your precious feedback.
Function name and view name do not need to be the same. Your view can be anything you want it to be so long as you call the filename (and sometimes path) correctly :)
The biggest problem I see here is you are trying to access some object called posts, which I do not see defined. I have a good hunch you're looking for the "input" object provided by code igniter.
That being said, replace:
$this->post->get_posts();
With:
$this->input->post(NULL,true);//return all post objects with cross site scripting scrub
And replace:
$this->post->get_post_by_ID($postID);
With:
$this->post->post('postID',true);//same as above, except again, with XSS scrub enabled.
If this is not your answer and you need me to re-evaluate, please let me know in a comment and I'll redo the answer.
With regards to your page not found issue, it's because Codeigniter automatically assumes the paths depending on what you name your functions. It uses the following convention by default (routes.php allows you to override this in config/routes.php)
site.com/index.php/controller_name/method_name/param_1/param_2/param_n
Or if you have mod_rewrite taking out the front controller
site.com/controller_name/method_name/param_1/param_2/param_n
Since the view is loaded from the controller function itself, if you change the name of that function, then the URL will no longer be able to "find" it, hence the error.
thanks to help me.
In CodeIgniter, I have a Controller named "Idee" in which there is this function :
public function index(){
$this->load->model("idee");
echo "Doesn t go ahead";
$data['idees'] = $this->idee->getAll();
var_dump($data);
$this->load->view("view_home", $data);
}
But when I try the URL, the page is blank, and even the echo is not reached.
It is weir because I already did this on others page, and it's working.
Could you help me please ? Thanls a lot !
You need to name your model something different from your controller. It is failing because you are trying to redeclare the same class (Idee). Usually in CodeIgniter you would call your model something like Idee_m (the file and class).