mysql> SELECT * from users order by last_name desc; +----+------------+-----------+-------------+ | id | first_name | last_name | category_id | +----+------------+-----------+-------------+ | 4 | jeebus | saves | 3 | | 2 | harry | potts | 2 | | 3 | miner | niner | 2 | | 1 | joe | blogs | 1 | +----+------------+-----------+-------------+ 4 rows in set (0.00 sec)
mysql> SELECT u.*, c.name from users u left join categories c on u.category_id = c.id order by last_name desc; +----+------------+-----------+-------------+-------+ | id | first_name | last_name | category_id | name | +----+------------+-----------+-------------+-------+ | 4 | jeebus | saves | 3 | three | | 2 | harry | potts | 2 | two | | 3 | miner | niner | 2 | two | | 1 | joe | blogs | 1 | one | +----+------------+-----------+-------------+-------+ 4 rows in set (0.00 sec)
Some people immediately commented that I was wrong in not telling her to plan for the future requirements and start with the user/category relationships as a separate mapping table. And often, I’d agree with that, but in this particular case, I think that’s a premature optimization that puts a lot more work up front, especially since she wasn’t even comfortable enough to figure out how to code the simpler relationship herself without help. There are gotchas when dealing with n:n relationship data (layout and prepopulation issues with the multiple select box, figuring out how to properly update relationships in the list, etc…), and it helps to have gotten to that point yourself. Using a mapping table and limiting it with a unique index on the mapping table will push off some of the UI issues, but I pointed out that making the db change later is the least difficult part of this migration, and it can be done with two sql statements that don’t affect any existing data:
mysql> create table user_categories ( -> id int auto_increment primary key, -> category_id int, -> user_id int -> );
Query OK, 0 rows affected (0.12 sec)
mysql> insert into user_categories (category_id, user_id) (select category_id, id from users); Query OK, 5 rows affected (0.03 sec) Records: 5 Duplicates: 0 Warnings: 0
At the point at which you need to do this, it’s a trivial change shrouded in the other more complicated things you’ll be doing at the same time to support real n:n relations, and the code you need to use to interact with it in the meantime can be simpler. And, of course, if the requirement to have more than one category per user never materializes, you’ve saved yourself some work upfront.
Sometimes planning for the future is a good idea, and you should always keep it in mind, but that doesn’t mean it’s always the right way to design your data structures. Sometimes the value of the simpler shortsighted case outweighs its potential drawbacks.
I’ve known for a while that iCal has the ability to share calendars using WebDAV, but I’ve never bothered to set it up locally. I looked into it recently, and it’s really easy to do, since the OSX Apache install comes with the dav module already installed.
These instructions assume some basic familarity with Apache configuration and the unix shell. I’d be happy to write up a more detailed guide if someone asks. This configuration took me about 10 minutes.
In /etc/apache2/http.conf, uncomment this line:
In that file, change the paths for DavLockDB, the /uploads alias, the Directory tag, and the AuthUserFile to where you want those files to live, and give write permissions to the _www user on the directories you choose (I made them owned and writable by the _www group). Add users to the LimitExcept block, and add those users to the file you chose as the AuthUserFile with htdigest (as indicated in the comments, without the -c option after the first one).
Restart the web server in System Preferences > Sharing.
Select the calendar you want in iCal, and select Calendar > Publish. Enter the url for your webserver (it will be something like “http://thatserver.local/uploads”) and the authentication details. It should tell you that it was published successfully. If not, examine /var/log/apache2/error_log to see what went wrong. If it worked, go to another iCal and choose Subscribe, and enter the url to the new ics file (something like “http://thatserver.local/uploads/Adam.ics”), and set the options you want - it’s most useful if you have it auto-update.
As it turns out, my problem with git was that I was using push instead of pull to propagate my changes, and I think it had nothing to do with the fact that I was mounting the directory improperly. I’ve switched over to ssh because it’s a bit more transparent to me in daily usage, but I don’t think that was the issue. The issue was that push is not the opposite of pull, as you might expect, and the crash course for git for svn users doesn’t really make that clear: