Reputation: 16393
I have the following in my routes file
resources :details, only: [:show, :edit, :update, :new]
and in new.html.erb
<%= form_for(@detail) do |f| %>
<%= render 'fields', f: f %>
<% end -%>
and in the details controller
def new
@detail = Detail.new
end
When the new.html.erb is rendered, I get the following error message
undefined method `details_path' for #<#<Class:0x007fc4ac6bd730>:0x007fc4b62e7390>
What is causing this?
Upvotes: 0
Views: 678
Reputation: 76784
To give context to your answer, you need to look up about the resourceful
nature of Rails' routes:
Browsers request pages from Rails by making a request for a URL using a specific
HTTP
method, such asGET
,POST
,PATCH
,PUT
andDELETE
. Each method is a request to perform an operation on the resource. A resource route maps a number of related requests to actions in a single controller.
When you say... "form_for
helper is looking to post to /details
", it's actually looking to post your form data to the create
method. The way it does this is through the POST
verb on the /details
route:
Thus, you need to ensure that you're declaring your create
route if you wish to use the resourceful routing structure.
This is why you'll need the following:
#config/routes.rb
resources :details, only: [:show, :edit, :update, :new, :create]
or
resources :details, except: :index
--
Of course, you don't have to use it.
You can use whichever routes you want. The important thing, though, is to understand that Rails is built around convention; HTTP's is towards resources
:
The server, which provides resources such as
HTML
files and other content, or performs other functions on behalf of theclient
, returns aresponse
message to the client
This is why you have "resourceful" routing etc.
On top of Rails' object orientated nature, you need to appreciate which resources are being used at certain points in your app.
form_for
expects a new
object to route to the create
route. You can override this by using the url:
option:
<%= form_for @object, url: none_resourceful_path ...
Upvotes: 1
Reputation: 7921
The create and index actions use the same path but different actions. So if you have either in the routes file, then a details_path
method will be generated. In your case you want to make sure you have the create in your routes file:
resources :details, only: [:create, :show, :edit, :update, :new]
Upvotes: 1
Reputation: 16393
The cause of this is that the the form_for helper is looking to post to /details
. So it is not looking for the index path but the :create path.
So you need to add the :create action to your routes declaration
resources :details, only: [:show, :edit, :update, :new, :create]
If you look at the rendered html in this case, it will look like this
<form class="new_detail" id="new_detail" action="/details" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" />
so you can see why you need the :create path which makes the post /details path.
Upvotes: 4