I went with the unique composite field index method (unique across 3
fields, not just 2), with my database as follows:
db.define_table('likes',
Field('username', 'reference auth_user'),
Field('songname', 'reference songs'),
Field('playlist_name', 'reference playlist'))
if auth.is_logged_in():
already_liked = db((db.likes.username==auth.user.id) & (db.likes.
playlist_name==request.vars.playlist_name))
db.likes.songname.requires=IS_NOT_IN_DB(already_liked, 'likes.songname')
I also changed my add_like() controller function to the following:
def add_like():
ret = db.likes.validate_and_insert(username=auth.user.id, playlist_name
= request.vars.playlist_name, songname = request.vars.songname)
if ret.errors:
already_liked = (db.likes.username==auth.user.id) & (db.likes.
playlist_name==request.vars.playlist_name) & (db.likes.songname==request.
vars.songname)
db(already_liked).delete()
return "like removed"
else:
return "like added"
I used the web2py ajax function to call the add_like action. The whole
process seems somewhat sluggish, are there any unnecessary database calls
I'm making?
On Tuesday, September 11, 2012 4:53:44 AM UTC-7, villas wrote:
>
> How about: in 'likes' make a unique composite index of both fields
> (created at DB level). Try to insert a record. If it fails (because of
> the index) then delete instead.
>
>
> On Monday, September 10, 2012 11:58:03 PM UTC+1, Mark Li wrote:
>>
>> I have 3 datatables as follows:
>>
>>
>> db.define_table('songs',
>> Field('songname'),
>> format='%(songname)s')
>>
>> db.define_table('likes',
>> Field('username', 'reference auth_user'),
>> Field('songname', 'reference songs'))
>>
>> with the 3rd table being db.auth_user
>>
>> I would like to implement a "like" button, where clicking it adds an
>> entry to the intermediate table 'likes'. For example, if User1 likes Song1,
>> it would perform the following:
>> db.likes.insert(username=auth.user.id, songname=1)
>>
>>
>>
>> Right now I have the like button as the following in the view:
>> {{=A('like me', callback=URL('add_like'))}}
>>
>> and the function as:
>> def add_like():
>> db.likes.insert(username=auth.user.id, songname=1)
>>
>> The problem I'm having is that a user should only be allowed to 'like' a
>> song once; if the user has already liked the song, clicking on 'like' again
>> should remove that like. Basically a toggle functionality for the 'like'
>> button.
>>
>> I'm not sure how to implement the last part, as it seems checking the
>> entire database for the existence of that record on every 'like' click is
>> overkill. Is there an eloquent way (minimal database calls) to go about
>> implementing this toggle functionality for a 'like' button?
>>
>>
>>
>>
>>
>>
--