Ruby on Rails 5.2中form_for表单可创建无法更新,路由匹配失败求助
Hey there, let's work through this frustrating issue you're facing. When your create action works fine but update throws that route error, it's almost always because your form is sending a POST request instead of the PATCH/PUT request Rails expects for updates. Here's how to fix it step by step:
1. Double-Check Your Routes
First, make sure your config/routes.rb is set up with proper RESTful routing for your messages. The standard way is:
resources :messages
This automatically generates all the necessary routes, including the PATCH /messages/:id route needed for updates. If you're writing custom routes instead, don't forget to specify patch or put as the HTTP method for the update action—using post here will break things.
2. Ensure form_for Is Bound to a Persisted Object
In your edit.html.erb view, your form_for needs to use the existing @message object you fetched in the edit controller action (the one with an id attribute, since it's pulled from the database). That's how form_for knows to generate a PATCH request instead of POST.
Your form should look like this:
<%= form_for @message do |f| %> <!-- Your form fields go here --> <%= f.label :content %> <%= f.text_area :content %> <%= f.submit "Update Message" %> <% end %>
If you accidentally used Message.new here (like in your new form), form_for will default to a POST request for creating a new record—hence the route error.
3. Verify the CSRF Token is Present
Rails automatically adds a CSRF token to form_for submissions, but if it's missing, it can cause unexpected routing or security errors. Check your page's source code to make sure you see a hidden field like this:
<input type="hidden" name="authenticity_token" value="your-token-here">
If it's missing, confirm your application layout (app/views/layouts/application.html.erb) includes <%= csrf_meta_tags %>—this lets form_for inject the token automatically.
4. Manually Specify Route and Method (If Needed)
If the above steps don't work, you can explicitly tell form_for which route and HTTP method to use:
<%= form_for @message, url: message_path(@message), method: :patch do |f| %> <!-- Form fields --> <%= f.submit %> <% end %>
This forces the form to send a PATCH request to the correct update route, bypassing any automatic detection issues.
Quick Side Check: Confirm Your message_params
While this isn't the cause of your current route error, make sure your message_params method permits all the fields you need to update, so you don't hit another issue once the route works:
private def message_params params.require(:message).permit(:content, :title) # Replace with your actual fields end
内容的提问来源于stack exchange,提问作者Junior Chung

