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?
>>
>>
>>
>>
>>
>>

-- 



Reply via email to