Multiple controllers with a single model - php

Heres what im trying to do
Ive got table that holds many different types of data for items. the model name for this is 'Object'
for example :
row 1 : item_type = event
row 2 : item_type = news
row 3 : item_type = booking
i want to write a controller 'event_controller' and use the 'Object' model with it and only deal with item_types of event. and another controller for news (news_controller) and use the same model.
how do i do this on cakephp.
Im coming into cake from codeigniter and in CI we can load any model we want into any controller can i do something similar with cake?

It's considered poor form to use var $uses in CakePHP 1.3+. It's been replaced by App::import (see below)
Given you have a Users controller with User model, and a Comments controller with Comment model. The accepted patterns are:
Using Associations
This is your best bet if the models can be logically associated.
// models/user.php
Class User extends AppModel {
public $hasMany = array('Comment');
}
// controllers/users_controller.php
Class UsersController extends AppController {
function allComments() {
$this->User->Comment->find('all'); // You can use this across multiple models (e.g. $this->User->Comment->NestedComment->find('all');
}
}
Instantiating the model object
This will load your model file, add the instance to CakePHP's object map, and returns the instance.
// models/user.php
Class User extends AppModel {}
// models/comment.php
Class Comment extends AppModel {}
// controllers/users_controller.php
Class UsersController extends AppController {
function allComments() {
$Comments =& ClassRegistry::init('Comment');
$Comments->find('all');
}
}
Using $this->loadModel
Internally this uses ClassRegistry::init, then also adds the model as a property of the controller.
// models/user.php
Class User extends AppModel {}
// models/comment.php
Class Comment extends AppModel {}
// controllers/users_controller.php
Class UsersController extends AppController {
function allComments() {
$this->loadModel('Comment');
$this->Comment->find('all'); // using load model allows you to access it via $this->Model
}
}
App::import
This is really just the CakePHP way of requiring a file. You'll still need to instantiate the object.
// models/user.php
Class User extends AppModel {}
// models/comment.php
Class Comment extends AppModel {}
// controllers/users_controller.php
App::import('Model', 'Comment');
Class UsersController extends AppController {
function allComments() {
$Comment = new Comment();
$Comment->find('all');
}
}
I hope this helps.
Edit: If you want to use the model object globally within the controller, you can use any of these patterns I specified within your beforeFilter().

I would like to suggest you to not to $uses statement. Instead of that you can use relations of the models like $this->Model->M0del1->....->someFunc(); if the relation exists.
If the relation between the models dos't exist then simply use $this->loadModel('ModelName'); in the specific function where-ever you need it.
If you use var $uses = array('Object'); it becomes global to the controller and it will load that model for all the actions of the controller despite of whether you require it or not. This will affect your performance.
If you use $this-LoadModel('ModelName'); in a particular function it will only load in that function not in all the actions.

You declare your controller and declare the $uses variable on it like this:
var $uses = array('Object');

Related

Casting model to another model that extend the original

I'm trying to cast a model to another one that extends the same model.
Is there a build in way in Laravel this achieve this?
Example
In the code below I would like to cast User to ExtendedUser
class User extends Model
{
...
}
class ExtendedUser extends User
{
...
}

CakePHP - change Model variable on Controller

I have a Node Model with variable translateFields (using CakePhp):
class Node extends AppModel {
public $translateFields = array('title');
.....
}
For any case (not all), I want change to:
public $translateFields = array('title','field_image');
How I do this? Change in Controller or where?
See all Models inherit AppModel ,correct? So define the variable in AppModel. Therefore it will be accessed as will be defined in parent. Also you can override like you used different array indexes.Hope it makes sense.
In a Controller or another Model which uses the Node model:
$this->Node->translateFields = array('title','field_image');
In a method of Node:
$this->translateFields = array('title','field_image');

Binding models inside controller actions in CakePHP

Normally I load model inside classes like this:
public $uses = array('Table1', 'Table2', 'Table3');
But some of my models are only used by 2-3 actions. So I don't want to load that model for other actions. So I need to declare "table1" controller wide. And load "table2" and "table3" when I need them inside controller. Is it possible? I couldn't find inside cookbook.
Something like this:
class myController extends Controller {
public $uses = array('Table1');
public function myaction() {
$uses = array('Table2','Table3');
....
}
}
CakePHP uses lazy loading since v2.x, i.e. if you specify a model in the $uses array it is only loaded when it is really used, so it's fine to use your first snippet.
But if necessary you can also use the loadModel() method to load a model in a single action:
public function myaction() {
$this->loadModel('ModelName');
$this->ModelName->doSomething();
...
}
In any controller method you can import models when required:
App::Import('Model', 'YourModel');
$foo = new YourModel();
Now you can call methods by referencing from the model Variable e.g.
$foo->myMethod()
Instead of:
$this->Model->myMethod();

Codeigniter: How to obtain a(nother) handle to a loaded model?

Suppose we have this code:
class My_controller extends CI_Controller
{
private $model_name;
function __construct($model_name)
{
$this->model_name = $model_name;
}
function index()
{
//Use the model here
}
}
How should I create a handle to the model, to be used in the index function?
I mean I don't know the name of the model, so how should I access it?
--EDIT--
Normally, we would be loading a model like this:
$this->load->model('some_model');
$this->some_model->doSomething();
Here, we know the name of the model.
Now, suppose that My_Controller is a class, which some other controllers inherit from. Each class which inherits from My_Controller, set the $model_name property. Here we don't know the name of the model, so we need a handle to that model. How should that handle be retrieved?
I hope this clarifies a bit.
Thanks in advance.
You can give a model an alias.
$this->load->model($this->model_name, '', 'some_model');
$this->some_model->doSomething();

How to access a plugin model from a regular controller in PHP Cake 1.1

Hopefully a simple question: I've a plugin which uses a set of tables (kb_items, kb_item_tags, etc). and I'd like to be able to access these models from another controller (say, my Pages controller), thus:
class PagesController extends AppController{
function knowledgebase(){
$items = $this->KbItem->findAll(...);
}
}
I am admittedly breaking the rules a little (by not placing this controller inside the knowledge base plugin), but this in this case its a custom page that doesn't need to be part of the knowledge base plugin code base.
Please let me know if you need more details. Thanks in advance for any help!
I just had to do this myself, and putting the model name in the 'Uses' array does work. If you don't need to access the model in multiple controller actions, you can also use loadModel() to access it in just the actions you need. For example, let's say you only need to access this model in the view() action of a given controller:
function view() {
// load the model, making sure to add the plug-in name before the model name
// I'm presuming here that the model name is just 'Item', and your plug-in is called 'Kb'
$this->loadModel('Kb.Item');
// now we can use the model like we normally would, just calling it 'Item'
$results = $this->Item->find('all');
}
Hope that helps.
Not sure if it works like this in 1.1 but in 1.2+ you prefix the model name with the plugin name and a period in the controller's uses array:
class PagesController extends AppController
{
var $uses = array('Page','Kb.KbItem');
function knowledgebase()
{
// This now works
$items = $this->KbItem->findAll();
}
}
Just add the models to your controllers' $uses property:
class PagesController extends AppController
{
var $uses = array('Page','KbItem');
function knowledgebase()
{
// This now works
$items = $this->KbItem->findAll();
}
}

Categories