I have an issue trying to retrieve associated model data from another associated model.
I have Donor Model which is associated with BloodGroup Model (belongsTo/hasMany rel).
Now, I also have a Donation Model which is associated with Donor Model (again, belongsTo/hasMany rel).
From the Donation Model, I want to retrieve data from the BloodGroup Model.
Currently only the Donor related data is retrieved. The idea is that I do not add a blood group field inside the donation, but map the blood group of a donation, on the fly, through the donor that made the donation!
I have been checking out the containable Behavior but I am not sure if this is how I can do it! It seems that it is used to 'contain' and filter data from associated models rather than to extend associations.
Any help appreciated very much, as always!
[EDIT]
DONOR MODEL
class Donor extends AppModel{
public $belongsTo = array(
'BloodGroup'=> array(
'className' => 'BloodGroup'
),
'DonorType' => array(
'className' => 'DonorType'
)
);
public $hasMany = array(
'Donation' => array(
'className' => 'Donation',
'foreignKey' => 'donor_id',
'order' => 'Donation.created DESC',
'limit' => 10,
'dependent' => true
)
);
DONATION MODEL
public $belongsTo = array(
'Donor' => array(
'className' => 'Donor',
'counterCache' => true,
)
);
From the Donation Controller :
public $paginate = array(
'order' => array("Donation.d_date" => 'desc'),
'limit' => 10
);
$this->Paginator->settings = $this->paginate;
$donations = $this->Paginator->paginate('Donation');
$this->set('donations',$donations)
Result retrieved :
[donations] => Array
(
[0] => Array
(
[Donation] => Array
(
[id] => 1
[donor_id] => 4
etc..
)
[Donor] => Array
(
[id] => 4
[name] => ...
)
)
)
It's not clear what data you actually want to get, but to answer what appears to be your hope:
"From the Donation Model, I want to retrieve data from the BloodGroup
Model."
Because there's a related path, you can get BloodGroup data, from the Donation model like this:
$this->Donor->BloodGroup->find('all');
Or by using Containable:
$this->find('all', array(
'contain' => array(
'Donor' => array(
'BloodGroup'
)
)
));
There's a lot of options - it just depends on what data you need.
For details on how I use find()s in my Model while still paginating, see this answer: https://stackoverflow.com/a/6577042/673664
(there are likely a lot of ways to do this - this is just the one I use, and works great for me)
If the BloodGroup has many Donor and if Donor has many Donation, You can retrieve Donation data from BloodGroup but you have to set the recursive to 2 ($this->Donation->recursive = 2;) before you use find method. If you want output blood group data from donation. Try that.
Related
So quick overview of what I'm trying to do. User hasMany BusinessUnitsUser. BusinessUnit hasMany BusinessUnitUser.
In this manner, I've normalized their relationship to two hasManys (I hate working with HABTM related data).
On a new user form, I'd like to give the user the option of adding a new Business Unit at the same time.
Currently, my $this->request->data array looks like this:
Array
(
[User] => Array
(
[title] => Mr
[first_name] => Kyle
[last_name] => O'Brien
[username] => 55546#mylife.unisa.ac.za
[producing_office_id] => 4
)
[BusinessUnit] => Array
(
[name] => lskfjsldkfjsdlfk
)
)
Now, this is obviously incorrect, but I'm struggling to think of how to resolve this. I thought giving you a visual of the array, you might be able to tell me what my array should look like.
Here's my relationship array in BusinessUnitsUser:
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'BusinessUnit' => array(
'className' => 'BusinessUnit',
'foreignKey' => 'business_unit_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
EDIT (thanks ndm)
Note the goal: I'm adding a user and I may or may not be adding BusinessUnitsUser associations as well but I'm definitely also going to be adding a new BusinessUnit - the form for which exists on the new_user form.
Currently, the User is saving with a $this->User->saveAll($this->request->data) but NOT the new BusinessUnit and certainly not the new BusinessUnitsUser entry (which I expect to contain the new user id and the new business unit id.
Save via the join table model
The solution should be pretty simple, for that type of association you'll have to save via the join table model (even if you don't save additional data on the that table):
$this->User->BusinessUnitsUser->saveAssociated($this->request->data);
See also http://book.cakephp.org/.../saving-your-data.html#saving-hasmany-through-data
That way the ORM can properly save the belongsTo associated data, and create an appropriate record in the join table, using foreign key values obtained from the save operations for the associated data.
I have a function where a user can request a project. The request has 2 fields for other employees to be added.
It's got a field for a person who is responsible for the project (person_responsible) and the employee who is supposed to attend the opening meeting (person_attending).
What I want to know is, since both these fields (person_responsible and person_attending) will be pulling it's data from hr_employees table, how would I set this up in my Project-Model.
At the moment I have the one field set up like this:
public $belongsTo = array(
'HrEmployee' => array(
'className' => 'HrEmployee',
'foreignKey' => 'responsible_person',
'fields' => 'HrEmployee.employeename',
)
);
How would I set up the other field?
What I do in this cases is to make two associations. Since cake allow to customize relations, you can have two relations to the same model with different names.
public $belongsTo = array(
'ResponsibleEmployee' => array(
'className' => 'HrEmployee',
'foreignKey' => 'responsible_person',
'fields' => 'HrEmployee.employeename',
),
'AttendingEmployee' => array(
'className' => 'HrEmployee',
'foreignKey' => 'person_attending',
'fields' => 'HrEmployee.employeename',
)
);
Change the names to adjust your needs. Now, if your model is set as containable and you retrieve the Project model with those models in it, you'll get something like
array('Project' => array(/*data project*/),
'ResponsibleEmployee' => array(/*name*/),
'AttendingEmployee' => array(/*name*/)
)
(or another variation of that array depending on how the query was made).
I have got stuck on Multilevel associated tables in Cake PHP code.
I have the following models
Guardian who has many students and the various students have their studentfees. When I create a guardian with 2 students, an associated 2 row must be created for StudentFees table. Im successful in adding 2 students when adding a guardian, but I dont know how to add the 2 rows of fees for the student. My code is as below.
class Guardian extends AppModel {
public $name = 'Guardian';
public $recursive =2;
public $hasMany = array(
'Student' => array(
'className' => 'Student',
'dependent' => true
)
);
}
class Student extends AppModel {
public $name = 'Student';
public $hasMany = array(
'StudentFee' => array(
'className' => 'StudentFee',
'dependent' => true
)
);
}
class StudentFee extends AppModel {
public $name = 'StudentFee';
public $belongsTo = array(
'Student' => array(
'className' => 'Student',
'dependent' => true
)
);
}
Pl help me to save the studenFee details too. I use SaveAssociated function that saves guardian and Student details.
If I understood you correctly, this should do the trick:
Model::saveAll() should take care of it for you and select the appropriate method, saveMany or saveAssociated. Moreover, it will automatically set your foreignKeys so everything is neatly inserted into the database.
$this->Guardian->saveAll(array('Guardian' => array(
[...],
'Student' => array(
0 => array(
[here's your first Student],
'StudentFee' => array(
0 => array(
[here's your first StudentFee]
)
)
)
)
)));
can use saveAll and saveAssociated methods.
You can try using this method, which i always use in such situations :
$this->Studentfee->create();
$this->Studentfee->set(array(
'field1' => 'value',
'field2' => 'value'
));
$this->Studentfee->save();
and you can put in a loop for all student fees
I have a service where users are able to upload cars to the site, and select the manufacturer and model from a list. If the car model does not exist, the user can save a new model under the specific manufacturer.
Now to my problem, all models have to be confirmed by a moderator as being a valid type, having a correct spelling, and not being a duplicate etc. All confirmed models are visible to other users. I do this by specifying a condition in the Car's association as below:
$belongsTo = array(
'CarModel' => array(
'className' => 'CarModel',
'foreignKey' => 'car_model_id',
'conditions' => array('CarModel.confirmed' => 1),
'fields' => '',
'order' => ''
));
However, I want to override this condition in the edit action so that the user can see his models, even if they are not confirmed yet. Is that possible in the find conditions?
Regards,
Roland.
You can bind model before calling find() method. Try this in your action.
$this->ModelName->bindModel(
array('belongsTo' => array(
'CarModel' => array(
'className' => 'CarModel',
'conditions' => array('CarModel.confirmed' => 0), // Define your new condition here
)
)
)
);
$data = $this->ModelName->find('all'); // Now you will get the data for new condition applied
Hope it will work.
Im using cakephp and Im stuck about the idea of listing multiple models, here's my scenario:
I have two major models namely Task and Events. I used the Events model to track all changes. this has the ff fields: id, model, model_id, changed
I used Events table to track multiple model changes. so when something changed to Task model it will be logged to Events models (get the idea??)
What I want to do is whenever i used the find method for Event model, i want to list the model information (for example, the Task model) together with my Events information like this:
array(
[0] => array (
[Event] => array(
id => 1
model => Task
model_id => 2
changed => array()
)
[Task] => array(
id => 2
name => Task 1
descp => Test Task
)
)
)
Note: The model can be any model, it can be Projects model.
At my task.php, it is no problem because i can easily declare:
var $hasMany = array(
'Events' => array(
'className' => 'Events',
'foreignKey' => 'model_id',
'dependent' => false,
'conditions' => array('Events.model' => 'Task')
)
);
I can get Events information using the find method on task although using
$this->Task->Event->find('all');
will not work, i dont know why.
So as soon as I declare, something like this in my Event Model:
var $belongsTo = array(
'Task' => array(
'className' => 'Task',
'foreignKey' => 'model_id',
'conditions' => array('Event.model' => 'Task', 'Event.model_id' => 'Task.id'),
'fields' => '',
'order' => ''
)
);
will throw an SQL error. Do you guys have an idea how to implement it??
Thanks in advanced. :)
I use polymorphic models all the time. The reason that $this->Task->Event->find('all') doesn't work is that you were performing the find on the Event model which, until you defined its belongsTo association, didn't have any means of retrieving the Task info.
As for now, the only thing I see that looks odd is that you've aliased your Task association as Events (plural) rather than its singular version which is the convention for models. You also identified the className as the plural version.