I have a question that's been bugging me all afternoon:
I'm making a guitar gear site, so I am using a gear items table, a user table, and gear-to-user bridge table. That is, a user can own multiple items and items can belong to multiple users. So HABTM.
An item belongs to a brand (e.g. Fender - Stratocaster), so I set up a belongsTo relationship in the item model as well as a HasMany relationship in the brands model. When I check the output in the items controller, the gear and its associated brand's data is all there as it should be.
The user control panel (and similar areas) basically list all of the user's owned items. After setting up the HABTM relationship between users and items, I checked the controller's output. While the item's information and the bridge table information all appeared, the item's associated brand information did not. The results should essentially be a list of items, including brand information, as if it were "where user_id = x". Instead, it seems to only be grabbing the item information and none of its relationships.
Is there something I'm missing or a dumb mistake? Thanks.
Did you consider setting/changing the recursive attribute when performing find() on the User?
The higher recursive is set, the deeper associations will be found.
An alternative might be to use the Containable behavior on User:
$this->User->find('first',array(
'conditions'=>array('User.id'=>1),
'contain' => array('Item'=>array('Brand'))
));
Set the recursive level up or you can use ContainableBehavior
Related
I am currently exploring MongoDB.
I built a notes web app and for now the DB has 2 collections: notes and users.
The user can create, read and update his notes.
I want to create a page called /my-notes that will display all the notes that belong to the connected user.
My question is:
Should the notes model has an ownerId field or the opposite - the user model will have a field of noteIds of type list.
Points I found relevant for the decision making:
noteIds approach:
There is no need to query the notes that hold the desired ownerId (say we have a lot of notes then we will need indexes and search accross the whole notes collection). We just need to find the user by user ID and then get all the notes by their IDs.
In this case there are 2 calls to DB.
The data is ordered by the order of insertion to the notesIds field in the document.
ownerId approach:
We do need to find the notes by their ownerId field across the notes collection which might be more computer "intensive".
We can paginate / sort the data as we want - more control over the data.
Are there any more points you can think of?
As I can conclude this is a question of whether you want less computer intensive DB calls vs more control over the data.
What are the "best practices"?
Thanks,
A similar use case is explained in the documentation. If there is no limit on number of notes a user can have, it might be better to store a userId reference field in notes document.
As you've figured out already, pagination would be easier in the second approach. Also when updating notes, you can simply updateOne({ _id: "note_id", userId: 1 }) instead of checking user's document if the note actually belong to the user.
I am looking for direction on how to model something for a database. What I am trying to model is this: I have a list of Services. Each service can be made available to a list of countries. Each Service, that is avialable to that Country may or may not actually be being used in that country, so I need to capture that too.
I model this as three tables. CountriesTable, ServicesTable and Services_CountriesTable. The Services_CountriesTable has a column for the Services ID, Country ID and Is_Being_Used, which is aa boolean for whether or not the country is using the Service.
On the application, the user can edit a page about the Service and they can pick from a list of check boxes, for Countries that the services is available in. When the pick countries from the available Countries list, the UI then adds those countries to a second list of checkboxes, that the user can tick to say the country is actually using the service.
This works fine. But, I was asked to include an option, in the list of Countries, for "Worldwide" which is comprised of multiple countries (I can also see other options be requested to have added that would be similar). So, the user can just select Worldwide as the countries the Service is available in.
This causes problems for the Services_CountriesTable table, as I can no longer use it to also track which countries are actually using the service. Since I currently store that value in the relationship in the Country_Service table (Country_ID, Service_ID, Is_Using). But, if I introduce Worldwide, I can't use this because the Country_ID would be for Worldwide, but what would Is_Using mean? Some countries might be using it, but others may not
I could make a set of four tables (Services, Countries, Services_Countries_Available, Services_Countries_Using) but they would all be joined in a circle, which doesn't seem right. Is there a better option to model this?
I have a hasMany through schema for volunteers who make up teams. It's like this:
Volunteers belong to many Teams
Teams belong to many Volunteers
Both through a table of Memberships.
The reason why I used a through table is because I need to select certain volunteers as team leaders in certain teams they participate in. The field is boolean --TINYINT(1)-- and part of my join table. This is similar to CakePHP documentation's example of starred, I assume, on which an element is selected as highlighted.
Now, I am wondering on how to select volunteers as team leaders on an form in a way that I can load the list of associated volunteers (or during the selection page) and then mark a checkbox for 'team leader' for each name, or a widget that allows me to select only from the reduced list of volunteers already members of this team. So far, I have decided to leave the associated volunteer selection in the team edit page:
<?php echo $this->Form->control('volunteers._ids'); ?>
Which is pretty easy and straightforward, but from here, But I can't seem to find a way to generate the selection box for the already-reduced list of volunteers. I've found everywhere for an example of this, but I probably don't have the skill level to make a good search, as I'm not sure how to word my question, I guess.
Can you please help me out? I understand that a through table has a belongTo relation, but I don't know whether CakePHP generates the list of inputs for me, or whether I need to create a loop (which would mean that I need to add something on the controller to do so).
Thank you!
I have a project about nurse and patients. Nurse goes around and visits patients. The problem that I'm facing is that the nurse wants to see a list of all the visits they did for a patient.
I do have two admin pages, one is the patients admin (allows to create/edit patients) and another one that allows to log visits. Within the visit you select the patient. From the patient list, how can I list all of the visits a nurse did for a patient? and further more, allow to click an add button to log a new visit.
I don't have code to show, but if any of you can point to some documentation, or sample code, will be much appreciated.
On the patient edit page you could do the following. Assuming your entity is called something like VisitLogs. You can add the following to configureFormFields
$formMapper->Add('VisitLogs', 'sonata_type_collection' ['type_options' => ['btn_add' => true]], ['inline' => 'table', 'edit' => 'inline']);
This should display a table with the Visitlogs based on the patients (if the ORM is correctly setup) and shows a add new button.
I hope this somewhat helps you a little bit further. More information.
Note This is for the one-to-many relation. I'm guessing for the many-to-one relation you should use sonata_type_model not sure about that though.
I have 2 tables subscribers and distribution list and the relationship between them is HABTM. Now here particular users are associated to distribution list, i wish to add more users, but when adding new users to distribution list, i would like to show users who are not associated with that distribution lists. what condition should i write
$this->DistributionSubscriber->find('list', array('conditions'=>array('distribution_id <>' => 1), 'fields'=>array('subscriber_id'), 'recursive'=>-1));
I would try something like this. You want to start with the join table in this case, and do your find() from there. I haven't checked this syntax, but you should get the idea.