skip to Main Content

I have a bit complex query that I need help with:

Logic

  1. Table subscriptions have rows with user_id (each user can have many rows)
  2. Table products require tokens (example 2 tokens is required for product A)
  3. Now this tokens has to be calculated based on user subscription amount. Let say user has 2 rows in subscriptions table, one with 1 token and other one with 5 tokens (user have 6 tokens in total) and he need to use 2 of them only.
  4. What I’m trying to do here is to update subscriptions table for this user and mark his rows used_tokens column by incrementing them.

You might be confused a bit now! here is screenshots to make it
visually understandable for you.

products table

one

subscriptions table

two

Issue

Issue is I cannot make it happen to update used_tokens columns in this two rows in subscriptions table.

Here is what it should look like at the end

three

Code

This is what I have so far (getting right product, getting user subscriptions) and I need to update those subscriptions:

$product = Product::findOrFail($request->input('product_id')); // Get product
$required_tokens = $product->required_tokens; // Get product require tokens (i.e. 2)
$subscriptions = Subscription::where('user_id', $user->id)->where('isPaid', true)->where('used_tokens', '<', 'tokens')->get(); // Get user subscription rows

How can I update (increment) used_tokens in those rows?

2

Answers


  1. How about something like that?

    $product = Product::findOrFail($request->input('product_id'));
    $required_tokens = $product->required_tokens;
    $subscriptions = Subscription::where('user_id', $user->id)->where('isPaid', true)->where('used_tokens', '<', 'tokens')->get();
    
    $remaining_tokens = $required_tokens;
    
    foreach ($subscriptions as $subscription) {
      if ($remaining_tokens > 0) {
        $row = DB::table('subscriptions')
           ->where('id', $subscription->id)
           ->first();
    
        if(!empty($row)) {
          $available_tokens = $row->tokens - $row->used_tokens;
    
          if ($available_tokens > 0) {
            $tokens_to_be_used = ($remaining_tokens >= $available_tokens) ? $available_tokens : $remaining_tokens;
    
            $final_used_tokens = $row->used_tokens + $tokens_to_be_used;
    
            DB::table('subscriptions')
               ->where('id', $subscription->id)
               ->update([
                   'used_tokens' => final_used_tokens,
               ]);
    
            $remaining_tokens = $remaining_tokens - $available_tokens;
          }
        }
      }
    }
    

    Final (cleaned up) code

    $subscriptions = Subscription::where('user_id', $user->id)->where('isPaid', true)->get();
    
    foreach ($subscriptions as $subscription) {
        if($subscription->used_tokens < $subscription->tokens){
            if ($required_tokens > 0) {
                $available_tokens = $subscription->tokens - $subscription->used_tokens;
                $tokens_to_be_used = ($required_tokens >= $available_tokens) ? $available_tokens : $required_tokens;
                $final_used_tokens = $subscription->used_tokens + $tokens_to_be_used;
                DB::table('subscriptions')
                ->where('id', $subscription->id)
                ->update([
                    'used_tokens' => $final_used_tokens,
                ]);
                $required_tokens = $required_tokens - $available_tokens;
            }
        }
    }
    
    Login or Signup to reply.
  2. You can update multiple models at once in laravel using laravel eloquent relationships

    #AppModelsUser.php
    class User extends Authennticable {
        public function subscriptions ()
        {
            return $this->hasMany(Subscription::class);
        }
    }
    

    After setting this relationship, you can update the user’s subscriptions using the code below:

    $user = User::find($id);
    
    $user->subscriptions()->where(isPaid, true)->upadte(['used_tokens' => 'new_value']);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search