CakePHP: HABTM + 1 - php

I have a site that scrapes all the episodes from tv.com from certain series.
So my database has a User table, a Show table, an Episode table, a Show_User table (to associate shows with users, HABTM), an Episode_Show table (to associate episodes with shows, HABTM), a Episode_User table (to associate episodes with shows, only as a way of marking them as 'watched').
Now I want to add a way of marking an episode as 'downloaded' too.
So at the moment, the Episode_User table has two fields, Episode_Id and User_Id. Should I create a new table entirely for this? Or just add a field to the Episode_User table?
I'm using CakePHP's automagic features, and don't particularly want to break it. But if I have to, I have to...
Thanks for any advice.

I don't see why you would want to create a new table for episodes a user has downloaded. To me it would make the most sense to modify the Episode_User table to have a field for watched and a field for downloaded, since it's all relating back to the same pair of entities, users and episodes.
However, any time I've stored information about a relationship between two tables in that manner, I've found that regardless of the framework I'm using, the ORM inevitably become more complicated, but I don't think there's any way around there.
With CakePHP for handling those kinds of complicated situations, read up about the model behavior, Containable. It's not very well documented in the CakePHP book, but is really quite useful in a situation where you need to use the fields in Episode_User, for example, if you needed to find all of the users that had watched a particular episode, but not downloaded it.
Also, it occurred to me, while reading your post, that you could possibly make your data model more simple by having a hasMany relationship between shows and episodes. An episode will never belong to more than one show, so your episodes table could just have another field, show_id, which related back to the show table, and you wouldn't even need the Episode_Show table.

Related

PHP MYSQL Show tracker, how to mark episodes as watched

I am learning PHP the fun way, by making something useful. I'm making a personal PHP/MYSQL website for tracking watched episodes of tv-shows, and it's going quite good so far, albeit messy.
I have a user table, a episode table and an series table. Each of these are self explanatory I guess. What I want to do is make each user in the user table able to track what episodes have been watched. (Each single episode is in the episode table with a field that joins it with the Series table to keep track)
What I cannot get my head around is this:
How can I track if said user has watched said episode?
The only solutions I've come up with is
Add a field in the episodes database with the userID and mark them as 0 or 1, which isn't a very nice solution.
Even worse; each user has a "watched_id" field with several values for each watched episodes.
I know enough to know that this is not a good approach,
how can I approach this more effectively?
You need to create a many-to-many relationship using a mapping table ie. named "watched" with the following fields
id
user_id
episode_id
watched_at
...
Hope that helps. There is a lot of documenteation on the net if your searching for "many-to-many relationship", here is just an example:
http://www.joinfu.com/2005/12/managing-many-to-many-relationships-in-mysql-part-1/

Foreign key vs. SET data type MySQL

I have a MySQL database set up with a list of all my movies, which I imported from a MS Access database. One field contains the possible values for the genre of the movie, movies can have more than one genre, so I need a data type which supports this feature. In access I could link one table 'genre' to the field 'genre' in my table 'movies', so I could choose none, one ore multiple genres per movie. When I switched to MySQL I used the SET data type to define all the possible values. So far everything is running perfectly.
I am now trying to set up a table in html/php to show the mysql table. I want the table to be able to sort on: title, genre, quality, rating, etc. But for the sorting on genre, I would need the possible values from the set data type. I don't know if it is possible to get the values with some php command/code, but after I lurked around on the web for a while, I didn't see many applications where they use the SET data type for obvious negative reasons.
So I started looking into the Foreign Key possibility. The problem I have here is that -for as far as I know- the key can only contain one possible value, which puts me right back at the start of my problem. I do like the idea of a foreign key, because it would make it way easier for me to add a new genre to the list.
Is there a possibility I am overlooking? Is it possible to either get the values from the SET type to php or to use a foreign key with multiple possibilities for one record?
I know I can also put every genre in my php script manually, but I'd like to have it all on one place. So that if I add a movie with a genre I haven't defined yet, I can just update it at one place and everything else adapts to it.
Dagon is absolutely right here - you have an issue with the structure of the tables in your back end. You are wanting to model a many to many relationship when at the moment with your current back end the best you can do is a one to many relationship.
To review:
You have individual films that can have many genres
And you have individual genres that are related to many films
Relational databases actually don't model many to many relationships with one relationship they use recursion of the one to many relationship and create two joins.
To model a many to many relationship you need three tables
A film table (which I think you already have)
A genre table (which I think you already have)
A junction table which as Dagon suggests will consist of two fields film id and genre id.
You then set up two separate one to many relationships. One from the film table to the junction table and one from the genre table to the junction table.
Now if you want to know all the genres a film is in you simply filter the junction table on the relevant film id and if you want to know all the films with a certain genre you filter the junction table on the genre id.
Set up lookups to relate your genre ids to textual descriptions and bang you are free to change the textual description as much as you want and the great thing if you've done it right it will upgrade every single value in your forms.
This is an absolute fundamental concept of the algebra of sets behind the design of SQL and relational database design.

Proper way of doing a Twitter-like follower and retweets system on CakePHP 2?

I'm super new to CakePHP. I've searched everywhere for this but I can't seem to be able to get it right, or find any sort of orientation. I still don't get how the whole HABTM thing works and I'm expecting to learn more from this.
I'm trying to do a Twitter-like system, with users and followers, and posts (tweets) and shares (retweets). I've set up the users and posts models, and join tables for followers (between users and users) and shares (between users and posts). How should I set up my model associations? I've been trying several ways but I'm not certain on whether I'm doing it right or not.
And the other question is, what would be the proper find query to get all posts by the people I follow, plus the posts they've shared, without getting all the unnecessary data like user info and such, just the posts in one array? Is it possible with find in one query, or should I do several and then merge the arrays? Plus, it would be extremely useful to understand how to properly filter and limit this rather complex query (obtaining a "posts timeline" between certain date ranges, limit the posts to a certain amount, or both).
I know my question is a little bit silly, but I swear I've done a lot of research and I can't seem to be able to get it right. So any help, especially with the query part, would be greatly appreciated.
Thanks!
So these would be some weird relationships. I'm feeling you should have the following tables:
Users (with alias Followers) hasMany tweets
Posts belongsTo Users
UsersFollowers (A HABTM table)
To make this work on just three tables, Posts would need to be a threaded table. In essence, if a person retweets (shares) a post a new record is created with the id of the original post in the new posts parent_id column. Then when the record was called the model could pull up the additional data and include it in the feed.
The alias aspect of Users allows for the follower part to be done in just one table. To find followers of a person, search with one key of the table (follower_id) and to find the people a person follows just search with the other key (users_id).
As for the second part of your question, finds should be pretty easy in this setup, but you might want to read up on Containable and threaded queries. You could include timestamp columns in the tables so you could later do a search by date feature (or a post timeline).

Is it better to have separate tables for articles & comments, or one table for both?

I am working on a little project where a user submits an article to MySQL, and then PHP send the post to the screen. So far so good.
Now i want to extend it to a "two level" post system, where people can comment on the articles.
The case is, i dont know how to do that.
The table i use for storing articles:
TABLE: posts
id user date avatar signature post
Should i make a new row named comments in the posts table, or should i place the comments in a seperate table? one for articles, one for comments?
All help is much appreciated.
Depends on how you use it on your website. You have to ask: "are my articles and comments essentially the same concept?" If yes, then use one table, if no, use two. On most websites articles work differently, can be categorized, editted etc., and usually need a different fields which would clutter the comments table... so in that case two tables are more reasonable. But if you conclude that on your website articles and comments are generally the same (but try to think future proof: wouldn't you need to add some article functionality in 2 months?) then you can think of articles also as of comments and have one table for them.
If you decide to merge things to one table, and you realize that you need another column to distinguish type of the post, and that some columns remain unused for some types, it is a clear warning signal you should have two tables!
This is a little subjective, but I would just set up a parent/child relationship on your posts table, make a parent_id column that is a foreign key for the id column in the same table. for extra credit, you can make it a nested set relationship which will allow you to pull the parent and all the children in one query

How to handle groups of users and single users in data models

I'm working on a CRM system that will have both individual users as well as "teams of users". I'm encountering a problem in assigning tasks as I would like to be able to assign tasks/events/leads to individual users as well as to whole teams.
My problem is that traditionally my database table for tasks, leads, or events would tie that particular event to a user using a "uid" column. However, I'm not sure the best way to handle this (or how other systems handle this) type of thing.
I was thinking of adding a second column "is_team" that would be just be a bool. If the is_team column was set to true than the uid would be regarded as a team id for that particular row.
Any comments, suggestions?
What about nesting the Users, so you have a parent_id. In this parent_id a user can belong to a "virtual user" which is in fact a group. That way, one can assign an entity to a User or a Team.
Couple of thoughts.
First, you could remove the uid column from the tasks, leads, and events table and replace with a lookup table. You could either have two lookup tables, one for users and one for teams, or a single table that has columns for both users and teams.
Second, maybe re-examine your requirements. Do you really need the ability to assign to either a individual user or a team? In the instance of assigning to a single user, could you make them a team of one so that all things (tasks, leads, events, etc) are only associated with a team (even if that team only has one member)?
No matter what you choose, just try to keep it simple and be open to refactoring when/if you figure out a better way to represent your data.

Categories