oronatur's avatar

Eloquent update with 'where' updates all rows in database

I'm very confused so I hope someone will be able to help me. I'm using this code:

$level = BuildingUser::where('user_id', Auth::user()->id)->where('building_id',$id)->first();
$level->update(['level' =>  $level->level + 1]);

This should, I thought, update the one row I'm getting, but it updates the 'level' column in the database for every single row in the table. The table I'm trying to update is a pivot table, if that matters. How can I change this so that it updates only the one row I'm getting with the 'where' statements, and not every single row?

0 likes
7 replies
tykus's avatar

Is that all the code, can you show the full method?

oronatur's avatar

@tykus

if($this->pay($id)) {
            $level = BuildingUser::where('user_id', Auth::user()->id)->where('building_id',$id)->first();
            $level->update(['level' =>  $level->level + 1]);
            //$this->addResourceGain($id);
            return redirect()->route('palace');
        }
        else {
            return redirect()->back()->with('failure2', 'You do not have the required resources to upgrade this building.');   
        }
 public function pay($id) {
        $cost = Building::where('id', $id)->first(['cost_gold','cost_wood','cost_stone','cost_sand','cost_copper','cost_tin','cost_iron','cost_silver','cost_bronze','cost_steel','cost_glass','cost_mithril']);
        $resources = Resource::where('user_id', Auth::user()->id)->first(['gold','wood','stone','sand','copper','tin','iron','silver','bronze','steel','glass','mithril']);
        $costArray = $cost->toArray();
        $level =  BuildingUser::where('user_id', Auth::user()->id)->where('building_id',$id)->first();

        $costNotNull = array_filter($costArray);
        $resourceName = array_keys($costNotNull);
        $true = 0;
        
        //check if user can afford
        foreach($resourceName as $resource) {
            $resourceKey = str_replace("cost_","",$resource);

            if(($resources->$resourceKey - ($cost->$resource*5*$level->level)) >= 0) {
                $true++;  
            }
        }
        
        //deduct resources now that we know the user can afford it all
        if(count($resourceName) === $true) {
            foreach($resourceName as $resource) {
                $resourceKey = str_replace("cost_","",$resource);
                $resources->$resourceKey = $resources->$resourceKey - ($cost->$resource*5*$level->level);
                $resources->save();
            }
            return true;
        }
        else {
            return false;
        }      
    } 
tykus's avatar

@oronatur very strange that the entire table should be updating; what do you get if you dd($level) after retrieving it?

As an alternative, you try increment:

if($this->pay($id)) {
  $level = BuildingUser::where('user_id', Auth::id())->where('building_id',$id)->increment('level');
    return redirect()->route('palace');
}
return redirect()->back()->with('failure2', 'You do not have the required resources to upgrade this building.');   
oronatur's avatar

@tykus Yeah, I thought so too. dd of level:

App\Models\BuildingUser {#1598 ▼ // app/Http/Controllers/BuildingController.php:34
  #connection: "mysql"
  #table: "building_user"
  #primaryKey: null
  #keyType: "int"
  +incrementing: false
  #with: []
  #withCount: []
  +preventsLazyLoading: false
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: false
  #escapeWhenCastingToString: false
  #attributes: array:3 [▼
    "user_id" => 8
    "building_id" => 1
    "level" => 9
  ]
  #original: array:3 [▼
    "user_id" => 8
    "building_id" => 1
    "level" => 9
  ]
  #changes: []
  #casts: []
  #classCastCache: []
  #attributeCastCache: []
  #dates: []
  #dateFormat: null
  #appends: []
  #dispatchesEvents: []
  #observables: []
  #relations: []
  #touches: []
  +timestamps: false
  #hidden: []
  #visible: []
  #fillable: array:3 [▼
    0 => "user_id"
    1 => "building_id"
    2 => "level"
  ]
  #guarded: array:1 [▼
    0 => "*"
  ]
}

Edit: Increment works, so thanks for that! I still wonder what was/is going on though.

tykus's avatar

@oronatur yeah, but that's why the update was failing to constrain itself.

Please or to participate in this conversation.