【问题标题】:Working with whereDoesntHave() in Laravel 5.4在 Laravel 5.4 中使用 whereDoesntHave()
【发布时间】:2019-04-15 08:30:50
【问题描述】:

如何实现一个范围,在该范围内,用户将在特定级别领取奖励,并且一旦他们领取奖励,奖励字段将不再显示他们已领取的奖励。比如:

用户在 20 级,在他的奖励面板上,有 3 个可用的奖励可以领取,10 级、15 级和 20 级。所以如果用户领取了 10 级奖励,它将不再显示在面板上,除了获得 15 级和 20 级奖励。

这是刀片的代码:

 @foreach(App\LevelRewards::getRewards()->get() as $rewards)
 @if(Auth::user()->level >= $rewards->level_required || Auth::user()->level == $rewards->level_required)
    @if(App\ClaimReward::claimLevel()->get())
            <div class="col-lg-2 col-md-3 col-sm-6 col-xs-6" style="margin: 5px 0px;">
               <div class="hovereffect">
                    <a href="#" class="d-block mb-4 h-100">
                   <input type ="hidden" name="id" value="{{$rewards->id}}"/>
                   <img class="img-responsive" src="{{asset('rewards_img/'.$rewards->picture)}}" alt="">
                    </a>
                <div class="overlay">
                 <h2 style="font-size: 14px;">{{$rewards->details}}</h2>
                 @if($rewards->type == 'physical')
                 <button type="button" class="btn btn-success btn-sm" data-toggle="modal" data-target="#claimPhysical" data-details="{{$rewards->details}}" data-id="{{$rewards->id}}" data-level="{{$rewards->level_required}}" data-physical="{{$rewards->item_name}}">
                CLAIM
                </button>
                @else
                <button type="button" class="btn btn-success btn-sm" data-toggle="modal" data-target="#claimDigital" data-id="{{$rewards->id}}" data-level="{{$rewards->level_required}}" data-physical="{{$rewards->item_name}}">
                CLAIM
                </button>
                @endif
      </div>
    <div style="background: #2d2d2d; padding: 9px;">
         <span class="credits_top">Required Level: <span>{{$rewards->level_required}}</span></span>
         <p>{{$rewards->item_name}}</p> 
    </div> 
</div>                                                                  
   @endif
  @endif
@endforeach

这是模型 ClaimReward 模型的代码:

public function scopeClaimLevel2($query)
{
    return $query->join('level_rewards','level_rewards.id','=','claim_rewards.reward_id')->select('level_rewards.*');
}

我们将非常感谢有关此问题的任何链接和信息来源。谢谢。

编辑:我试过了;

public function scopeClaimLevel($query)
{
    return $query->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')->select('level_rewards.*');
}
public function scopeGetRewards($query)
{
    return $query
    ->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')
    ->whereDoesntHave('claimLevel', function (Builder $query) {
           $query->where('claim_rewards.status', '=', '0');
     }) 
    ->select('level_rewards.*');
}

但它说 Call to undefined method Illuminate\Database\Query\Builder::getRelated()'

【问题讨论】:

    标签: php laravel-5 eloquent-relationship


    【解决方案1】:

    添加另一个表格来保存用户已经领取的奖励,

    并在 foreach 中检查此奖励 id 是否存在于该用户声称的奖励中,

    如果不是,则显示它,如果是,则跳过它。

    该表将包含 2 个字段:

    1) 用户 ID

    2)rewards_id

    【讨论】:

    • 我认为领取奖励已经包含以下内容:id、reward_id、user_id
    • 如果是这样,那么添加一个字段,如果它真的被认领了,它将保持状态,默认为0/false,选择后将变为1/true
    • 先生,我的 claim_rewards 表的状态也设置为 0。如果接受,则为 1,如果拒绝,则为 2。但是如果我像 whereNotIn 一样查询它,它不会显示任何东西,因为它没有任何东西要显示,也没有任何东西存在于 claim_rewards 表中。
    • 表格的结构可以帮助您,编辑后更清楚......任何方式看起来都需要更改查询的顺序
    【解决方案2】:

    关于上面的cmets,

    在您对您尝试过的内容进行编辑后,

    好像查询的顺序不对……把 whereDoesntHave 放在 select 前面,

    并按照 Laravel 文档示例中的说明更改它的实现。

    试试这个:

    public function scopeClaimLevel2($query)
    {
        return $query
          ->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')
          ->whereDoesntHave('claim_rewards', function (Builder $query) {
                 $query->where('status', '=', '0');
           }) 
          ->select('level_rewards.*');    
    

    }

    编辑:

    尝试更改联接,如此处所述:https://laravel.com/docs/5.4/queries#joins

    构建连接并在它的函数中设置如何连接以及 status=0 的位置

    return $query
          ->join('claim_rewards', function ($join) {
              $join->on('claim_rewards.reward_id', '=', 'level_rewards.id')->where('status', '=', '0');
          })
          ->select('level_rewards.*');
    

    【讨论】:

    • 我试过了,但它说 Argument 2 传递给 Illuminate/Database/Eloquent/Builder::whereDoesntHave() 必须是 Closure 的实例或 null。
    • 查看编辑代码...您确定需要检查 whereDoesntHave status = 0 ... 吗?必须是 1,对吗?
    • 我可以简单地将其编辑为 whereNotIn,但我只是测试了 where('claim_reward.status','=','0') 来测试它是否有效。现在,它返回唯一状态为 0 的数据,因此我添加了 whereDoesntHave('claim_rewards.status','=','0') 以返回用户尚未领取的奖励。
    • 我已经编辑了我的问题,请参阅上面的编辑部分。我刚才试过你的方法,但它返回调用未定义的方法 Illuminate\Database\Query\Builder::claim_rewards()
    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2017-10-04
    • 2017-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多