No route matches [POST] "/articles/new" - Why? - ruby-on-rails

I made the following introduction:
http://guides.rubyonrails.org/getting_started.html
And after that, I wanted to create a new field (like title) and got the error notification:
Here is my code:
routes.rb
Rails.application.routes.draw do
get 'welcome/index'
resources :articles do
resources :comments
resources :description
root 'welcome#index'
# For details on the DSL available within this file, see guides.rubyonrails.org/routing.html
end
end
I know that this question has been asked a lot but their solutions didn't helped me.
What should I do?
Regards

The problem is in your new.html.erb form, you are missing url: articles_path, if you don't specify it, the form will be sent to the same action (i.e. new). So, since submitting the form uses POST (by default) method, you get:
No route matches [POST] “/articles/new”
You need to change your form_for and specify the url, like this:
<%= form_for :article, url: articles_path do |f| %>
From the same link your provided:
There's one problem with this form though. If you inspect the HTML
that is generated, by viewing the source of the page, you will see
that the action attribute for the form is pointing at /articles/new1.
This is a problem because this route goes to the very page that you're
on right at the moment, and that route should only be used to display
the form for a new article.
1 My emphasis.

By default rails new resource route has a GET HTTP verb, not POST. Unless you specified otherwise.

Seems like you are using new_article_path or articles/new in the form
<%= form_for :article, url: new_articles_path do |f| %>
Change it to
<%= form_for :article, url: articles_path do |f| %>

Related

How to specify post path for rails partial form

I have a partial form that creates a post that is being rendered on it's parent model communities, however, it doesn't post the form to this path:
POST /communities/:community_id/posts(.:format) posts#create
Instead, it will try posting to the path it's rendered on. For example, No route matches [POST] "/communities/1" because I have the form on a community page.
This is running Rails 6 beta.
I believe a solution would be to specify the path for where it sends to in the form, but I cannot find anything in the documentation that matches that. Either I'm reading wrong, or it's a nonexistent solution and requires a different approach. I'm really not sure.
posts/_form.html.erb
<%= form_with model: #post, local: true do |form| %>
...
<% end %>
routes.rb
resources :communities do
resources :posts
end
You can just use the url option, i.e:
form_for #post, local: true, url: posts_path do |form|
Use the path helper, you can find it's name by doing rake routes

When the form is submitted with an error, the rendered url changes in Rails 4

I have created a user signup page. When the user submits the form incorrectly, when displaying a validation error, it does not render on the same URL.
The signup form is located at this url:
http://localhost:3000/signup
I have added the following routes for the signup page:
resources :users
match '/signup', to: 'users#new', via: 'get'
When I submit the form, the model validation shows up but the url redirects to:
http://localhost:3000/users
I want the user to remain at the same url after submitting the form.
http://localhost:3000/signup
This is my controller code:
def new
#user = User.new
end
def create
#user = User.new(user_params) # Not the final implementation!
if #user.save
# Handle a successful save.
else
render 'new'
end
end
This is the beginning tag of my form:
<%= form_for #user, url: {action: "create"} do |f| %>
I'm working with Rails 5, but I suspect it's not too different conceptually.
In routes.rb:
get 'signup', to: 'users#new'
post 'signup', to: 'users#create'
resources :users
and in your form helper:
<%= form_for #user, url: signup_path do |f| %>
Essentially, the reason why it's not working as described in your original post is because when the form posts (rails 4.2 form helpers), it's tied to url: {action: "create"}, which by default, according to the routes automatically generated for resources :users, is post '/users', to: 'users#create (rails 4.2 routing guide). And by searching top down in routes.rb, it'll see this first and you end up with http://localhost:3000/users.
So, the changes I propose, should bind the form to post to the signup path instead which, in routes.rb, is seen as the second route entry.
I believe that #Jaskaran's question is in regards to question 2 found at the bottom of Michael Hartle's Ruby on Rails Tutorial, section 7.3.3, so I will be answering in reference to that question:
How does the URL on the unsubmitted signup form (Figure 7.12) compare to the URL for a submitted signup form (Figure 7.18)? Why don’t they match?
To answer this question, we need to understand how routing works in a Rails application. Let's walk through what happens when you visit each page and make a submission.
Your main page (home.html.erb) contains a link to your signup page (new.html.erb). That link looks like this:
<%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %>
The signup_path is the part we are most interested in. signup_path is a route helper and essentially tells Rails that when someone clicks on that link, Rails should behave as if they just went to your /signup page. This is why the first URL you see (before submitting the form) shows http://localhost:3000/signup.
Now let's take a look at what happens when your form is submitted. According to the new.html.erb file, the form is contained within this Ruby code:
<%= form_for(#user) do |f| %>
. . .
<% end %>
You may remember from 7.2.2 that that Ruby code is actually rendered in HTML as:
<form class="new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post">
. . .
</form>
What that is saying is that when the form is submitted, it will make a POST request to /users - and that's the URL that you are seeing in your browser.
We can better understand why this is if we first stop to think - where does /users route to? You can quickly check your routes by typing bundle exec rake routes in your console. You should see it listed there:
Prefix Verb URI Pattern Controller#Action
users GET /users(.:format) users#index
POST /users(.:format) users#create
So any POST requests to /users will be routed to the create method of our users_controller.rb. If you're wondering why that is, it is because we added this line to our routes.rb file:
resources :users
More details on that line can be found here.

Rails form_for wrong method

I've got a weird issue with one of my forms. The form only changes one variable of the object, called admin_comment. It ends up in the show method of the controller, in the terminal:
Processing by EnrolmentsController#show as
Here is the form_for
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :get, remote: true do |f| %>
And here is the rake routes
enrolments_admin_comment GET /enrolments/admin_comment(.:format) enrolments#admin_comment
And the routes.rb part
get "enrolments/admin_comment"
resources :courses do
resources :enrolments
end
When I delete the method: :get part from the form_for, it ends up at the update method.
Everything else with the enrolments controller/model works fine. Does somebody know what's going on here? Thanks!
Update
After nearly getting insane I've got it working like this, but only with :get as method.
routes.rb
get "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
form_for
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :get, remote: true do |f| %>
If I change the method to :post, I get the following error:
ActionController::RoutingError (No route matches [POST] "/enrolments/28/admin_comment"):
Two questions came up:
1. What do I have to change to make it work with :post?
2. As far as I understand, if I just would just state the controller and the verb (:get / :post / ...), rails would know which method it has to use as the verbs are mapped to the methods. But when I state the whole path (controller and method), shouldn't rails know everything it needs without the verb? The form params are being sent anyway.
Update2
Ok, I've changed
get "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
to
post "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
Now everything works fine.
You'll be best looking at Rails' Resource Routing
HTTP Verbs
Each resources :controller you create in your routes.rb file creates a series of routes, which connect with relative HTTP Verbs:
The HTTP verbs part of the routing system is the most important, as it governs which controller action is loaded. You can use the same path helper with different HTTP Verbs to route to completely different controller actions
If you want to create a new path, you'd need to set the HTTP verb to method: :post, like this:
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :post, remote: true do |f| %>
Routes
Perhaps you'd be better with this routing structure:
resources :courses do
resources :enrolments do
get :admin_comment, shallow: :true
end
end

Rails routing error with nested resources

In my application, I have a RecipesController and a CommentsController. All comments belong to a recipe, and can be voted up. Here's a snippet from my routes.rb:
resources :recipes do
member do
put 'vote_up'
post 'comment'
end
resources :comments do
member do
put 'vote_up'
end
end
end
If I run rake routes, I find the following route in the output:
vote_up_recipe_comment PUT /recipes/:recipe_id/comments/:id/vote_up(.:format) {:action=>"vote_up", :controller=>"comments"}
The CommentsController has a method called vote_up.
Also, linking to the route works (from my view)
<%= link_to 'Vote up', vote_up_recipe_comment_path(#recipe, comment), :method => 'put' %> <br />
However, clicking on that link gives me the following error:
Routing Error
No route matches "/recipes/7/comments/4/vote_up"
What am I missing? I'm not sure how to debug this, because as far as I can see the route should match.
I think that you get this error message because the request is made via HTTP GET method, not PUT.
In order to create links that use POST/PUT/DELETE method, your application should correctly load a Javascript Rails adapter.
Check that your app has jQuery (http://github.com/rails/jquery-ujs) or Prototype JS adapter and that your layout correctly loads it.
try the following tweak: send the put method as a symbol
<%= link_to 'Vote up', vote_up_recipe_comment_path(#recipe, comment), :method => :put %>

ruby on rails form not doing correct action

I'm trying to edit a form, the route is controller/id/action for edit so for example
people/124321/edit
I'm trying to make this form submit to the update action using this code:
<% form_for :probe, #probe, :action => "update" do |f| %>
...
...
...
<%= submit_tag 'Submit' %>
<% end %>
When I click submit, it gives me an error stating
Unknown Action.
No action responded to (id).
Edit
The only thing in my routes specified for probes is map.resources :probes
RoR just did the people/124321/edit by itself when I generated the controller.
Rake routes shows this
probes GET /probes(.:format) {:controller=>"probes", :action=>"index"}
POST /probes(.:format) {:controller=>"probes", :action=>"create"}
new_probe GET /probes/new(.:format) {:controller=>"probes", :action=>"new"}
edit_probe GET /probes/:id/edit(.:format) {:controller=>"probes",action=>"edit"}
GET /probes/:id(.:format) {:controller=>"probes", :action=>"show"}
PUT /probes/:id(.:format) {:controller=>"probes", :action=>"update"}
DELETE /probes/:id(.:format) {:controller=>"probes", :action=>"destroy"}
Edit 2 Probe Controller
def edit
#probe = Probe.find(params[:id])
end
def update
#probe = Probe.find(params[:id])
debugger
if #probe.update_attributes(params[:probe])
flash[:notice] = "Successfully updated probe."
redirect_to probes_path
else
render :action => 'edit'
end
end
It's hard to say exactly since you have posted very little supporting details for your question, but my guess is that your routes file is set up such that the precedence of something matching :controller/:action/:id comes before the route you're aiming for, :controller/:id/:action.
Routes are evaluated top-down, first match wins.
I'll echo John's answer, too. You shouldn't need to specify :action => 'update', and in fact these days I usually extract the form out of both new.html.erb and edit.html.erb into a partial _form.html.erb. form_for will figure out if the object is a new record and POST to either the create or update action, as appropriate.
I have seen some situations in the past where route changes reloaded in development mode confuse the routing code, which is usually fixed by restarting the server.
rake routes is also a good debugging tool. Check the page source to see what Rails has used for the form's action attribute, then scan down the output of rake routes to see where the request will end up.
If you're using RESTful resources, then you should just be able to do this:
<% form_for(#probe) do |f| %>
.
.
.
<%= f.submit 'Submit' %>
<% end %>
Rails can work out whether you're creating a new record or updating an existing one. See Binding a Form to an Object for further details.
Also, note the use of f.submit in my example. The *_tag helpers go together, so you wouldn't usually see a form_for helper with a submit_tag.
"Unknown Action. No action responded to (id)." sounds like a routing problem.
Have you removed or commented out the default routes in your routes.rb file?
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
If the default routes are being run it could be swapping the id for the action?

Resources