带参数的Create控制器页面渲染失败(404错误)求助
Hey there! Let's figure out why your create action is throwing a 404 while the show action works perfectly. The URL you're using—http://myapp.test/country/us/state/create—gives us some key clues to work through.
1. RESTful Route Mismatch (Most Likely Culprit)
Rails sticks closely to RESTful conventions, and this is where things are probably going off:
- By default, a GET request to load a "new resource" form maps to the
newaction, notcreate. Thecreateaction is reserved for POST requests that submit form data to create a new record. - Your URL uses singular terms (
country,state) instead of the standard pluralized resource names (countries,states) that Rails expects for nested resources.
If you're using nested resources, your routes.rb should follow this structure (pluralized, with proper nesting):
# config/routes.rb resources :countries, param: :code do # Use :code instead of :id to match your "us" parameter resources :states end
With this setup, the correct URL to load the new state form is http://myapp.test/countries/us/states/new, and the form will submit a POST request to http://myapp.test/countries/us/states (which triggers the create action).
2. Missing or Misconfigured Custom Route
If you intentionally want a GET route for create (not recommended for RESTful practices), you need to explicitly define it in routes.rb:
resources :countries, param: :code do resources :states do get :create, on: :collection # Adds a GET route for /countries/:country_id/states/create end end
But again, this deviates from standard Rails patterns—stick with new for the form and create for POST submissions unless you have a specific reason to break convention.
3. Verify Your Controller Setup
Double-check that your controller is named correctly and includes the create action. It should look something like this:
# app/controllers/states_controller.rb class StatesController < ApplicationController def show # Your working show logic here end def new @country = Country.find_by(code: params[:country_id]) @state = @country.states.new end def create @country = Country.find_by(code: params[:country_id]) @state = @country.states.new(state_params) if @state.save redirect_to country_state_path(@country, @state) else render :new end end private def state_params params.require(:state).permit(:name, :code) # Adjust permitted attributes to match your model end end
Quick Debugging Step
Run rails routes in your terminal—this will print all your application's routes. Look for a route that matches GET /country/us/state/create (or the pluralized version). If you don't see it, that's exactly why you're getting a 404.
内容的提问来源于stack exchange,提问作者OhDavey

