tags:

views:

147

answers:

4

I have to make a view that shows unrelated data from multiple tables. I am new to cakePHP (and PHP in general) and as far as my understanding goes, each model is a depiction of just one table. I know that we can define associations with other tables, but in my case I need to give access to data that is no way related to the model who's view will be opened.

Example: Say there is a blogging platform and we are currently viewing a post. (Model - Post, function - Read). Now I want a list of (Say) subscribers of our newsletter. This data is not related to the model and hence, I don't think the data will be accessible to the controller. Please tell me how to get this data in view directly.

A: 

If you're going to use it in a couple of functions in the same model, you should specify it inside the Controller via:

$uses = array('Post', 'Suscriber');

Now, if it is a elemnt of the layout, you should set it on an element.

In the view:

$this->renderElement('suscribers-list');

Now you must create a suscribers-list.ctp file in views/elements. From there import the model:

App::Import('Model', 'Suscriber');
$this->Suscriber = new Suscriber();

$suscribers = $this->Suscriber->find('all');
pr($suscribers);

It's not pretty, but it's what works for me. I don't know if there's another way.

metrobalderas
+2  A: 

In your controller, when defining the class, add a class attribute $uses to tell your controller which models to load.

class SomeController extends AppController {
    public $name        = 'Some';
    public $uses        = array( 'Model1', 'Model2' );}

And then, in your method, you just call that model:

$result = $this->Model1->find('all');
$result2= $this->Model2->find('all');
kio
A: 

You can do this with less code, and slightly simpler. You can make use of the AppController::loadModel('ModelName'). (reference) This method takes care of initilization step that metrobalderas suggested so then if becomes

$this->loadModel('Subscriber');
$subscribers = $this->Subscriber->find('all', ... );

There was a function that was deprecated in 1.2 that was just loadModel('ModelName'); but not the AppController method. Also it should be noted that you should not directly load models in an element, as that is not really in the spirit of MVC. Keep that in the model. Using this method rather the var $uses = array('ModelName'); does reduce the overhead of the unrelated models in methods that don't need it, as well as reduces some of the complications that can occur when using that approach.

Sam D
+1  A: 

There are a few ways to do this. Here is gwoo's synopsis of how they differ and when to use which:

App::import() only includes the file. So you would new to create a new instance every time. This is not recommended

ClassRegistry::init() loads the file, adds the instance to the a object map and returns the instance. This is an easy and convenient way to access models.

Controller::loadModel(); Uses ClassRegistry::init() adds the model to a property of the controller and also allows persistModel to be enabled.

While you "can" do any of these things, you should ask yourself why you are creating dependencies on models that are not natural to the controller. If you "have" to do use any of these, then I would do so in reverse order of the way i described them. IE, Controller::loadModel () then CR::init() and actually I never use App::import() for models. Hope this helps.

See this page for the full discussion: http://groups.google.com/group/cake-php/browse_thread/thread/137c57b4eb010317

In addition, some other answers have suggested including the unrelated model in the $uses array, but I would avoid this method as it is really intended to tell the model which database table to use and implies that its members are central to the purpose of the model, which is not the case in the situation you describe.

Jimmy Cuadra