2017-08-29 41 views
0

我有一个问题,我无法包裹我的头。根据用户排名而不是得分排名

我正在使用Laravel框架。

我试图让基于位置排序表(即用户没有任何得分,他们只是有个展示位置)

我它是如何想的工作方式如下:

用户A =放置:1个

用户B =放置:10

用户B战胜用户A,然后用户B被放置为数1用户A被放置为数2,然后我希望它相应地更新所有其他用户。

我似乎无法找到一个可靠的方法来做到这一点。

+0

你的意思是所有的Laravel的魔术它不会为你做?我只是徘徊在周围。你只需要对数据库行进行更新。也许而不是放置你可以做比例。这会容易很多。 –

+0

@BrianGottier我不确定我是否遵循,我不知道你用百分比来表示你的意思。放置基本上是用户的等级。如果我要更新赢家和输家的排名,那么会出现重复(两位用户排名相同) - 我怎么能避免这种情况? – Classified

+0

其实,看看这个:https://stackoverflow.com/questions/5207267/update-increment-a-single-column-on-multiple-rows-at-once,并想象在那里的where子句。你也可以在查询中减去。不应该很难弄清楚。 –

回答

1

我不认为这是一个Laravel挑战,而是一个SQL挑战。解决这个问题可能很简单:基本上,你会询问失败者的实际位置,如果位置大于赢家,你什么都不做,否则你将把失败者的位置分配给新的赢家并更新表格的其余部分在位置列中加+1。

在代码中它会是这样的:

$winner_player = User::where('id', userA->id)->first(); 
$loser_player = User::where('id', userB->id)->first(); 

if($winner_player->position < $loser_player->position) { 
    //Update the rest of the users. 
    //We add 2 because we need space for the new winner and for 
    //the loser that is still above of the rest of the players. 
    DB::table('users') 
     ->where('position', '>', $loser_player->position) 
     ->update(DB::raw('position+2')); 

    //Set the winner with the actual position of the loser. 
    $winner_player->position = $loser_player->position; 
    $winner_player->save(); 

    //Set the looser with the new position (+1 of his actual). 
    $loser_player->position = $loser_player->position + 1; 
    $loser_player->save(); 
} 

修订LOGIC 作为分类中指出,它绕着行,但不这样做是正确,所以我更新逻辑使其按照预期工作,而且会稍微简单一些。

$winner_player = User::where('id', userA->id)->first(); 
$loser_player = User::where('id', userB->id)->first(); 

if($winner_player->position < $loser_player->position) { 
    //Set the winner with the actual position of the loser. 
    $winner_player->position = $loser_player->position; 

    //Update the users between the swap. There is no need to update 
    //the whole table, we only update the records between the swap. 
    DB::table('users') 
     ->where([['position', '<', $winner_player->position], 
       ['position', '>=', $loser_player->position]]) 
     ->update(DB::raw('position+1')); 

    //Save the value of the winner AFTER updating the positions 
    //between winner and loser. 
    $winner_player->save(); 
} 
+0

我会明确地尝试这个明天,并看看它是如何发展的。一旦我尝试并测试它,我会发表评论。 – Classified

+0

这解决了潜在的问题。然而,如果只有三个用户,这不能正确工作,那么如果第二名用户移动到第一名,那么第三名将是第五名。 – Classified

+0

你是对的!我假设所有记录都必须更新,但是实际上,需要更新的记录是位置交换之间的记录。我用新提出的逻辑更新了我的答案,让我知道这是否适合您! – Lvkz