tags:

views:

111

answers:

3

Okay... So, I came across the following problem: I have one table that works properly - it holds users' IDs, posts' IDs, posts' content, time that post was made.

I use it to have the following printed out: the content of the post, who is the author of the post and when the post was made. So far everything works just fine.

Now... I have a button that allows the users to vote up for a given post - everything is working just fine here as well. However, now I want to make one more feature that will show who and when has voted. You know, so that beneath each post there will be a list of people who have liked the post and when they've pressed the button.

My idea was to have two tables - the one holding the post's info post_table, and one more table voted_table that will have the user IDs, the time the button was pressed and the post_id that the vote has been made for... But I have no idea how to actually make it. So pretty much my question is:

How can I insert into a table information from another table + some other information on a button's click?

+1  A: 

You can if your database supports transactions. In mysql look for the key words BEGIN COMMIT and ABORT. However, if you do this, you'll be storing data in two places.

Alternately, you can store your vote totals in the voted_table and you can alter your first query to join to the voted_table to tally the votes.

select P.post_id, sum(V.votes) # add other post_table fields
from post_table as P, voted_table as V
where P.post_id=V.post_id
group by P.post_id #add other post_table fields you need here also
SorcyCat
Thank you, but if it was only about the mysql part - I figured it out. My problem is how to insert ON BUTTON'S CLICK into voted_table the voting_user_id, time_they_vote and post_they_vote for, so that later on I can print out who and when had voted.
Izumi
+1  A: 
CREATE TABLE `user` (
  `id` INTEGER UNSIGNED NOT NULL auto_increment,
  `username` varchar(32) default NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `post` (
  `id` INTEGER UNSIGNED NOT NULL auto_increment,
  `owner_id` INTEGER UNSIGNED default NULL,
  `content` TEXT default NULL,
 PRIMARY KEY (`id`),
 KEY `post_I_owner` (`owner_id`),
 CONSTRAINT `post_FK_user`
   FOREIGN KEY (`owner_id`)
   REFERENCES `user` (`id`)
   ON DELETE SET NULL
) ENGINE=InnoDB;

CREATE TABLE `vote` (
  `id` INTEGER UNSIGNED NOT NULL auto_increment,
  `user_id` INTEGER UNSIGNED default NULL,
  `post_id` INTEGER UNSIGNED,
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`),
   UNIQUE KEY `vote_IU_user_post` (`user_id`,`post_id`),
   CONSTRAINT `vote_FK_user`
     FOREIGN KEY (`user_id`)
     REFERENCES  `user` (`id`)
     ON DELETE SET NULL,
   CONSTRAINT `vote_FK_post`
     FOREIGN KEY (`post_id`)
     REFERENCES  `post` (`id`)
     ON DELETE CASCADE
) ENGINE=InnoDB;

So with the schema above we can do the following...

in your html/php for the viewPost page you could have

<form name="vote_form" action="postVote.php" method="POST">
  <input type="hidden" name="post_id" value="1" />
  <input type="submit" value="Vote for this Post" />
</form>

So then in votePost.php you could do something like:

if(isset($_SESSION['user']['user_id']))
{
   $userid = $_SESSION['user']['user_id'];
}
else
{
  // redirect to a login or something
}

$sql = "INSERT INTO vote (user_id, post_id) VALUES (%s,%s)"
$sql = sprintf($sql, $userid, $_POST['post_id']);
mysql_query($sql);

This way mysql will take care of the timestamp for you. Note that you need to verify/validate the input data (which i didnt really do here) before inserting it into the db and all that fun security stuff. Id also recommend using Mysqli or PDO Mysql instead of the old mysql libararies and using a prepared stament (that will take care of most of your value quouting/escaping functionality on its own)

prodigitalson
That way when I click the button it will automatically insert into the vote table the needed information, right?How will I link this information to the post id from the post table? Because... each vote should be linked to a given post from the post table...
Izumi
define "link" - are you talking relationship wise in the db, query wise pulling it out, or `href` wise as in an `a` tag?
prodigitalson
db/query-wise? I have a <form method=POST> that gives me the voting button and when I click on it, the vote goes up - it works, but I want to be able when I click on it, my information - user_id, time, to be inserted into the who_voted_table linked to the post_id from the post_table.
Izumi
All that info (post_id, user_id, created_at) are directly on my version of your voting table NOT on the post table. So the code that i gave you does what you ask - youre just inserting that info into the vote table instead of the post - you dont need to touch the post table at all for your voting mechanism.
prodigitalson
But... I still need a post_id in the post table... how else am I going to display the post itself if I don't call it from the post table?
Izumi
Your `post_id` should be auto generated (hence auto_increment in the create table query) - anytime you create a post it gets a `post_id` automatically same thing for primary keys on **ALL** of your tables. This post id is then referenced on the `vote` table as `post_id`. This means that a post must exist before it can be voted on... but that shouldnt be an issue...
prodigitalson
Tell you what make a test db and run the table creates i gave you (hopefully i didnt fat-finger anything) then insert some info into each table while not providing a value for the table's `id` column (note i didnt add any columns other than the id to user so you may want to add like first_name or something) magic will happen... MAGIC I TELL YOU ;-)
prodigitalson
Okay... then is this the part that does the reference between the two tables: FOREIGN KEY (`post_id`) REFERENCES `post` (`id`) ? Will it allow a user to vote more than once for a given post? The vote table will look like 'post_that_has_Been_voted_for|who_voted|when_they_voted' or?
Izumi
Actually they way i configured it a user can only vote once for each post - this limitation is defined by the statement `UNIQUE KEY (\`user_id\`,\`post_id\`)` which makes it so each user/post combination on the vote table can only occur once. If you want people to vote more than once then just remove the `UNIQUE` or split the keys up like `KEY (\`post_id\`), KEY (\`user_id\`)`
prodigitalson
I keep on getting a mistake when trying to make the tables: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'REFERENCES `user` (`id`) ON DELETE SET NULL )' at line 6
Izumi
Big OOPS on my part - i forgot to use constriant names. Updated the SQL Schema. Give it a try now...
prodigitalson
Still the same...
Izumi
3rd time is a charm.. tested it on Mysql 5.0 (should work for 5.x) - make sure you drop the tables first or drop/create the entire db. Also i added a couple columns just for my testsing (user.username, post.content) you can remove or adjust those accordingly.
prodigitalson
Thank you for all the tips and code and patience, but I figured it out. Using your logics and explanation managed to add to the part that does the voting a function that takes the post_id and sends it to the other table. Thank you again! <3
Izumi
+1  A: 

To run the insert query when the user clicks a button you need a couple moving part. First, you need to add a form with the button. You'll need to add enough information to the form using "hidden" fields (the post_id, and the user_id unless you can get that from somewhere else). You'll have to set the action on the form to be another PHP page. On the second PHP page, you get the form variables you specified and use that to generate your insert query. (There are security issues you should consider, like trusting the value of user_id and checking user input, but I won't go into that.) If you used method="POST" on your form, then you get the values with $_POST[$formFieldName].

SorcyCat