Laravel Eloquent用Switch Case更新指定字段:优化及报错解决
Hey there! Let's walk through what's causing that error and refactor this into a cleaner, more robust implementation.
First, Why You're Seeing That Error
The Call to a member function save() on null happens because UserJourny::find($request->session) is returning null—meaning there's no existing record for that session ID. On top of that, your switch statement is broken: you're switching on the entire $request object, which will never match your string cases like 'details_submitted', so no fields are being updated even if the record exists.
Better Implementation
Here's a streamlined, safer version that fixes both issues and makes your code easier to maintain:
use Illuminate\Http\Request; public function updateUserJourney(Request $request) { // Step 1: Validate incoming requests to block bad data $validated = $request->validate([ 'session' => 'required|string', // Adjust validation rule to match your session ID type 'stage' => 'required|in:details_submitted,has_seen_plans,has_compare,has_seen_plan_details,has_seen_proposal,submitted_proposal', 'value' => 'required|boolean' // Assuming all journey stages are boolean flags; tweak if needed ]); // Step 2: Get OR create the journey record (no more nulls!) $journeyObj = UserJourny::firstOrCreate( ['session' => $validated['session']], // Look for existing record by session ID // Optional: Set default values for new records [ 'details_submitted' => false, 'has_seen_plans' => false, 'has_compare' => false, 'has_seen_plan_details' => false, 'has_seen_proposal' => false, 'submitted_proposal' => false, ] ); // Step 3: Dynamically update the specified stage $journeyObj->{$validated['stage']} = $validated['value']; $journeyObj->save(); return response()->json([ 'message' => 'User journey stage updated successfully', 'updated_stage' => $validated['stage'], 'value' => $validated['value'] ]); }
Key Improvements Over Your Original Code
- Eliminates null errors:
firstOrCreateensures you always have a validUserJournyinstance—either fetching an existing record or creating a new one if the session is new. - Validates input: Blocks invalid session IDs, unknown stage names, and incorrect value types (e.g., non-boolean values for your flags).
- Simpler maintenance: No more long
switchstatements. Add a new journey stage later? Just update thein:list in the validation rule and your model's fillable attributes. - Security: The
in:validation acts as a whitelist, preventing attackers from updating arbitrary fields in your database.
Quick Model Setup Note
Make sure your UserJourny model has these fields in its $fillable array to allow updates (even though we're not using mass assignment here, it's a good practice for safety):
// app/Models/UserJourny.php protected $fillable = [ 'session', 'details_submitted', 'has_seen_plans', 'has_compare', 'has_seen_plan_details', 'has_seen_proposal', 'submitted_proposal', ];
How to Call This API Now
Send a POST request with these parameters:
session: Your user's session IDstage: The exact name of the journey stage to update (e.g.,has_seen_proposal)value: The boolean value to set (e.g.,truewhen the user completes the stage)
内容的提问来源于stack exchange,提问作者Prathamesh Doke




