Cakephp retrieve data in HABTM association - cakephp

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.

Related

filemaker database relationships

I'm very new to FileMaker currently working on a Mac. I've been assigned a new simple system to work towards completing and I have bumped into some issues with database relationships. I've got experience with PHP/MySQL databases connections etc. but FileMaker seems to require a somewhat different mindset and approach.
I'll try to explain this as simply as I can.
Here's the table relationships in my database
What I'm trying to do is a list of "to-do" notes, an interactive menu where the user can add things that needs to be done. I've done this with a portal on a layout based on the table "site". The portal is based on the table "todo_notes", which is connected to site through the "site_id".
Here's what it looks like in browse mode
What I'm having problems with is adding a relationship between the todo_notes and contacts. The contacts are two separate tables called "county_contacts" and "property_owner_contacts". What I want to accomplish is the possibility for the user to, from a dropdown-list, add a single contact from these two tables. Preferably I'd like to sort of merge these two tables into the same dropdown-list.
Let me know if you need any other information or a better explanation of my issue. Any help is very welcome!
If you have a single contacts table with foreign keys for both county and property owner tables, that would let you have a single list for all contacts. From there you could also build a value list based on a relationship, for example to filter only contacts that belong to either county or property owners.
If you then need to further normalize the tables, fields that pertain to either relationship exclusively could be moved to another table from there, as a one to one relationship, if that is a concern.
The Short Answer
You need to create a Contacts table. Filemaker has no way of dynamically generating value lists. Instead, you can base a value list on any field, therefore, the only way of generating a list of the contact names would be if they were all in the same table.
The Long Answer
Because Filemaker only allows us to use ONE field for a value list, we must create a new table for the contact. I would recommend that you replace the two contact tables with a single contact table,(seeing as the fields look the same between the two tables) and then add a toggle on the contact for Owner or County. However, you could also create a single contact table for all of the fields that overlap that has foreign keys to the owner and county tables.
You would then use the fullname field from the contact and be good to go.
That is, assuming that you did not want to filter the contacts at all or only show contacts associated with this site.
To start with, I highly recommend using the Anchor-buoy method for organizing the relationship graph. Here's an explanation of the anchor-buoy method: http://sixfriedrice.com/wp/six-fried-rice-methodology-part-2-anchor-buoy-and-data-structures/ . It's just a convention, but will help you with the idea of context in FileMaker. It's widely accepted among the FileMaker community as the "right" way to organize a relationship graph. I will continue my explanation using this method.
Each Table Occurrence (the boxes in the graphs, or TO) represents a unique context from which you can view and edit information. In the anchor buoy method, each Table only has one "anchor" TO. I would recommend only using anchor TO's for the context of your layouts. Then, your portal, and any other corresponding information, will be on your buoy TO's. Here is what your new portal relationship would look like. You would select fields from your buoy TO's to use in the portal.
The easiest way to filter your value list by only contacts associated with this site would be to create a foreign key from the contact table to the site, and then add a TO to the graph, for the contact table. You would then click "Include only related values starting from" radio button, and specify your new TO.

CakePHP2 Get Associated Model from DataSource

I have an User Model which uses a standard MySQL database and users table and a Movie Model which is a datasource from Rotten Tomatoes. They have a hasAndBelongsToMany relationship and I'm successfully able to write to the join table users_movies which holds the user_id and movie_id (the movie_id is the Rotten Tomatoes id). Works great.
The trouble is retrieving an User's movies. The standard find:
$movies = $this->User->find('all', array('conditions' => array('id' => $user_id)));
only returns the User not the associated Movie(s). I put a die statement in my read method in the DataSource and it's not even reaching the read method. How can I go about retrieving an User's movies?
So Rotten Tomatoes is holding your movies? In that case, of course Rotten Tomatoes wouldn't allow direct SQL access to their database - you'd be accessing it via an API. So Cake definitely won't just be able to join Users to Movies the way it normally would with two tables in the same database.
What you'll have to do is 1) get a list of the user's movie_id's from Cake, and then 2) Call the Rotten Tomatoes API to get a list of movies where their ID is in your list of movie_id's. (That's assuming rotten tomatoes allows such an API call.)
Having a quick look at the API, it looks like their 'movies search' (http://developer.rottentomatoes.com/docs/json/v10/Movies_Search) only allows you to specify plain-text as the search criteria (ie, you can't search based on movie id's). And their 'movie info' method (http://developer.rottentomatoes.com/docs/json/v10/Movie_Info), which does allow you to retrieve a movie by id, only allows you to retrieve one movie at a time.
You could of course loop through your list of movie id's for a given user, and make a separate API call to rotten tomatoes for each one - though I'd imagine that would get VERY slow.
Someone has put in a feature request for retrieving based on a list of multiple id's (http://developer.rottentomatoes.com/forum/read/123940) but until that request gets implemented, you will probably be having a tough time getting anything decent working.
I got it working by making a Model out of my join table between users and movies and getting an user's movies that way. Then I did as you suggested and looped through the user's movie ids making a call to the API and getting each movie. Not sure how elegant it is, but it is working.

CakePHP 2.1 HABTM Not Getting Associated Info

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

CakePHP search in hasMany relations

I have a model Content which belongsTo Categories, hasMany Publishers, and Publisher belongsTo city.
There is also a search form where someone selects from a drop-down box which category to view and which city.
But how can I combine these two in a single paginate condition? I mean I cannot do something like:
$this->paginate('Content',array('conditions' =>array('Category.id'=>$category,
'City.id'=>$city)));
because to get cities cake performs a different query.
Nor can I do something like:
$this->paginate('Content',array('conditions' =>array('Category.id'=>$category),
'contain'=>array('Publisher.City'=>array('conditions'=>array(City.id'=>$city)))));
because this will search according to category and filter the city results according to $city.
I know I can do something like:
$this->Content->Publisher->City->find(...)
but this will change the output of my paginated data.
What I usually do is write my custom query where I LEFT join all models and filter the results in WHERE. But I wanted to aks if there is a more cake (sic) way!
thanks
i've experienced the same thing when i first try to create a simple search engine with hasmany relationship.
i used multiple $this->find() and assigned it in a variable then on the paginate code i used$this->paginate(array_merge(name of the variables used in $this->find()));.
hope this will help you...
~gio

HABTM-Relation : Create a relation for all other records

If i want to add a record to TABLE A, is there an efficient way to add
a record in the JOIN TABLE for many (or all) records in TABLE B?
I try to build a simple task management (in CakePHP). An user adds a task and there
will be added a connection to each other user in the same group as the
current user.
At the moment, I use the find('list')-method to retrieve the IDs and
store them in a variable. But I think if the groups grow, the PHP
cache won't handle this amount of data in a single variable.
You should look into the Cake Has-And-Belongs-To-Many (HABTM) relationships. Check the cake book. It will allow you to create a relationship between two tables, using a join table, and will automatically retrieve and save values as requested in your application.
Please note, however, that from one model you cannot (by default) filter by criteria on the related model (in this case, the model related by the join table). To do this, you will need to use the Containable behavior, which will allow you to set filter criteria on the related tables.
The one other caveat is that I don't know of a way (out of the box) to add some information about the relationship in the join table. For example, if you wanted to record (in the join table) whether the user has completed the task, you would have to write your own stuff there. I usually get around this by creating a model for the join table, which I then invoke whenever I want to retrieve data specific to the joined relationship. By doing it this way, you can also easily pull up the data from the joined tables. Anybody else have a better solution?

Resources