0
votes

I'm developing a system for a University here in Brazil. In this sytem I've got the following models: - Country; - State; - City; - University; - Unit; - Class;

Ok. and the relations are: - State belongs to Country; - City belongs to State; - University belongs to Country (because, in my database, not every country has states registered to it and not every state has citys registered to it, so I could not demand from the user to register a University to a City); - Unit belongsTo university; - Class belongs to University (because not every University has Units registered to it);

Ok. I guess now I've set a good background for you guys to understand my situation. Now onto the question itself:

In the Views of my Model Class I wanna display the Country and (IF there are State City). And I may have the need to display such content in other Model views such as Unit and University.

But when I try to do that in my Class model I can only display the country_id. The foreign key in my university database table. And why is that, that is because my Class model belongs to University, so it's pretty easy to access my University's properties. However I do not wish to access the id of the Country, I want it's Name. And maybe in the future I might want other properties, who knows?

HOW DO I DO THAT? How do I access the properties of the Model Country when my Model Class has NO direct relation to it?

many thx hugs and kisses. Hope someone can help me with this one.

p.S: I've managed a kinda loser solution: In my Class Controller I've done the following (so I can access variables of the Models Country, State and City):

  • In the View function I've loaded the Models for State and City (the country Model I can access by the relation Class->University->Country);
  • Then I used a find method to find the respective country, state and city for the Class in question I wanna display in view.ctp. The code follows:

    public function view($id = null) {    
        $this->Class->id = $id;
        $this->set('class', $this->Class->read());  
        $this->loadModel('State');  
        $this->loadModel('City');  
        $country = $this->Class->Universsity->Country->find('first', array('conditions' => array('Country.id' => $this->Class->data['University']['country_id']),));  
        $state = $this->State->find('first', array('conditions' => array('State.id' => $this->Class->data['University']['state_id']),));  
        $city = $this->City->find('first', array('conditions' => array('City.id' => $this->Class->data['University']['city_id']),));  
        $this->set('country',$country['Country']);$this->set('city',$city);  
        $this->set('state',$state);  
    }
    

And it kinda works...In my Wiew.ctp I get an array for Country data, and array for State data and an array for City data. And in the view I check to see if the state and city arrays are not length = 0 to display them and all...but I think there HAS to be a better way to do This.

P.P.S:

The other question is...what about the Index.ctp? How will I do that if I do not know which Class I'm working with? Will I have to have logic and find methods in the View? Isin't that just messing up the code?

1

1 Answers

1
votes

Without posting your code, it's difficult to point you in the right direction. However, working on the assumption that you have your models configured correctly you should be able to do the following:

ClassController.php

public class ClassController extends AppController{

    public $uses = array('Class');

    public function view($id){
        $class = $this->Class->find('first', array('conditions' => array('Class.id' => $id));
        $this->set('class', $class);
    }
}

view.ctp

<?php echo $class['Country']['name']?>

You may find however you will have to configure the recursive parameter of your class model so that CakePHP retrieves all the associated data. This can be done one of two ways:

  1. Configure the recursive parameter within your Class model (see the documentation on how to do this). This sets the default value for recursive whenever you retrieve records from the database and you don't specify the attribute in your options.
  2. Set the recurisve parameter within your find(...) method calls. I favor this one because it helps avoid placing a heavy load on the database when you don't need the data it retrieves.

For example, in your controller you could do the following:

public function view($id){
    $class = $this->Class->find('first', array('conditions' => array('Class.id' => $id), 'recursive' => 3));
    $this->set('class', $class);
}

Just a warning, don't set recursive to a value higher than you need, otherwise you may retrieve stuff that you don't particularly require. Use the debug() function to inspect what you're model is currently retrieving so you can make more of an informed decision:

debug($class);

I hope this is of some help!