Rails应用赛事对阵图提交问题:JSON payload传数据库异常求助
Hey there, let's figure out why your bracket save feature isn't working as expected. Based on the code you shared, here are the key issues to check and fix:
1. Missing Rails CSRF Token
Rails enforces CSRF protection by default, and your XMLHttpRequest isn't including the required token—this will almost certainly result in a 403 Forbidden error when you try to submit.
Fix:
Grab the CSRF token from the page's meta tags and add it to your request headers:
function save() { var data = { payload: myDiagram.model.toJSON() }; var jsonPayload = JSON.stringify(data); myDiagram.isModified = false; // Fetch CSRF token from Rails meta tag const csrfToken = document.querySelector('meta[name="csrf-token"]').content; // Complete XMLHttpRequest setup const request = new XMLHttpRequest(); request.open('POST', '/tournois', true); // Replace with your actual Tournoi create route request.setRequestHeader('Content-Type', 'application/json'); request.setRequestHeader('X-CSRF-Token', csrfToken); // Critical for Rails CSRF protection // Handle request completion request.onload = function() { if (request.status >= 200 && request.status < 400) { console.log('Bracket saved successfully!'); // Add success UI updates here if needed } else { console.error(`Save failed with status ${request.status}:`, request.responseText); // Show error message to user here } }; // Handle network errors request.onerror = function() { console.error('Network error occurred while saving bracket'); }; request.send(jsonPayload); }
2. Form Default Submission Interference
You're using form_for Tournoi.new but handling submission via custom JS. The button's default behavior (triggering a form submit) might be overriding your AJAX request.
Fix:
Add type="button" to your save button to prevent default form submission:
<%= form_for Tournoi.new do |f| %> <button id="SaveButton" type="button" onclick="save()">Save</button> <% end %>
Or, if you don't need the form for anything else, you can remove the form_for block entirely to avoid any unintended behavior.
3. Backend Controller Not Handling JSON Params
Make sure your TournoisController is set up to accept and process the payload parameter correctly, including strong parameters:
class TournoisController < ApplicationController def create # Log incoming params to debug (check Rails logs) Rails.logger.info "Received bracket data: #{params.inspect}" @tournoi = Tournoi.new(tournoi_params) if @tournoi.save render json: { status: :success, message: 'Bracket saved' }, status: :ok else render json: { status: :error, errors: @tournoi.errors.full_messages }, status: :unprocessable_entity end end private def tournoi_params # Adjust this based on your Tournoi model's attributes # If you're sending { payload: ... } as top-level data: params.permit(:payload) # If you nest it under a :tournoi key (common for form_for): # params.require(:tournoi).permit(:payload) end end
Double-check that your Tournoi model has a payload column (or whatever field you're using to store the bracket JSON) to avoid database errors.
4. Debugging Tips
- Open your browser's DevTools (F12) → Network tab: Watch the AJAX request to check its status code, request headers, and response body. This will tell you if the issue is on the frontend (bad request) or backend (processing error).
- Check your Rails server logs: Look for any error messages or missing parameters when you trigger the save.
内容的提问来源于stack exchange,提问作者Dezz H

