Rails routes an invalid URL

I wrote the form in a different user perspective, which allows visitors to log in. I want to check first if this works. Therefore, I am doing the "index" action for the test.

<%form_tag(:controller=>"users",:action=>"index") do %> Name: <%=text_field_tag "name" %><br> Password: <%=password_field_tag "password" %><br> <%=submit_tag "Login" %> <% end -%> 

Surprisingly, route routing directs the page to a β€œnew” view while the browser navigation bar is displayed:

 http://0.0.0.0:3000/users 

When I refresh the page, it displays the regular "index" page.

Why is this happening?

More terribly, when I changed :action in the code above to :action=>"new" , the message "Routing error" appears on the screen. When I update it, it presents a normal "new" view.

users_controller.rb as follows:

 class UsersController < ApplicationController def index @users=User.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } end end def show @user = User.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @user } end end def login flash[:notice]="Hello"; end def new end def create @user = User.new(params[:project]) respond_to do |format| if @user.save format.html { redirect_to(@user, :notice => 'user was successfully created.') } format.xml { render :xml => @user, :status => :created, :location => @user } else format.html { render :action => "new" } format.xml { render :xml => @user.errors, :status => :unprocessable_entity } end end end end 

My .rb routes look like this:

 Testdrive::Application.routes.draw do resources :users do member do post 'login' end end resources :cars 
+4
source share
2 answers

The appendicitis answer is correct, however I think it is important to clarify some things:

On which page are you trying to get the user? It looks like you want the user to go to the index page (you are surprised that the user lands on a new page).

First: you need to understand the relationship between the type of HTTP request you make and the place where the controller directs the browser. See http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions

Basically your form sends a POST request to the URL /users . The controller always routes POSTS to this address in the CREATE action. Thus, as Apneadiving explained, the message parameters sent are not what CREATE expected, so the save is not performed, and you are redirected to users/new

Now I see that in your form you specified:: :controller => 'users', :action => 'index' . So this is where I see it, it seems you want people to land on the index page. However, you need to understand that Rails form helpers are not magically related to the controller level.

Second: Know that the flow of information is mostly one-way in Rails: things from the model can go to the controller, but not the other way. Things from the controller can go to the view, but not the other way.

The only thing the controller can get from the user is an HTTP request. When you use form tag helpers, you simply use a shortcut to define the action and method attributes of the HTML form element. See http://www.w3.org/TR/html401/interact/forms.html#h-17.13

So, although you specified :action => 'index' , your form still submits a POST request (by default it forms POST). The controller does not know that you wanted the request of the person to fall into the action of the index, he only knows that he received POST, and not GET, at the URL /users . Therefore, it sends this request to the CREATE action.

What is REST.

Decision:

You need to use an action that has not yet been predetermined. On your routes, it looks like you tried to do this when you put:

 resources :users do member do post 'login' end end 

This code will correctly accept POST requests to users/123/login .

However, since you specified this in the MEMBER of the user collection, and not in the collection itself, you will need to specify a specific USER_ID so that this request is processed correctly. Since you use this action to log in, this is not what you need. See http://guides.rubyonrails.org/routing.html#nested-resources

Instead, you need to specify this route for COLLECTION (i.e.: users/login ):

 resources :users do collection do post 'login' end end 

Then in your form, change your form tag to say :controller => 'users', :action => 'login' .

Finally, in your controller you will need to specify the login action. In this case, it could be simple:

 def login redirect_to users_path end 

All that will do is get the POST and redirect to the index. However, if you want the parameters from your form to stick, you need to process them in the LOGIN action. They will not be saved and will be available to your INDEX action after the redirect.

Hope this all makes it easier for you. Good luck

+5
source

Your problem is your routes. rb. Take a look here . The example is very clear:

 resources :photos do member do get 'preview' end end 

Description: "This recognizes / photos / 1 / preview using GET."

So, back to your code: the post login line will not lead to where you intend.

Instead, the post request is directed to the create view because this is what you requested by typing resources :users (see here ). Since it was not saved correctly, it is redirected to the "new" view, due to:

 else format.html { render :action => "new" } 

So what is the solution? Here are a few tracks:

  • check your logs, they should be a resource for debugging
  • use rails s --debugger to set breakpoints and check your variables
  • check your parameters, I don’t understand why you rely on params[:project] to create a new user.
+2
source

Source: https://habr.com/ru/post/1336681/


All Articles