2017-04-06 61 views
0

当我在我的rails项目上处理用户表单中的验证错误时,如果用户无效,我有指令render 'new'呈现'新'导致不同的网址

但是,当发生这种情况时,搜索栏中的网址会发生变化。

原来,这是https://localhost:3000/signup但是当用户提交表单和render 'new'发生时,URL成为https://localhost:3000/users

这是为什么?

这里是我的routes.rb

Rails.application.routes.draw do 

    # Resources 
    resources :users, only: [ :new, :create ] 

    # Application root 
    root 'static_pages#home' 

    # Static pages 
    get '/help', to: 'static_pages#help' 
    get '/contact', to: 'static_pages#contact' 

    # Users 
    get '/signup', to: 'users#new' 

    # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 
end 

感谢,

回答

-1

您需要添加

post '/signup', to: 'users#new' 
+0

虽然这确实解决了直接的问题,但它带来了一些历史相关的问题,而轨道约定旨在避免这些问题。在破解规则之前了解规则。 – max

0

你尝试包括认识路?

Rails.application.routes.recognize_path 
1

出现这种情况的原因是因为Rails的处理路线的方式。最有可能的,你的注册页面上的表格有一样的东西:

<?= form_for @user do |f| ?> 

如果你看一下生成的HTML你会发现,形式张贴到URL '/users'。所以当提交注册表单时,应用程序会将您重定向到/users

这是Rails中的正常行为。 (见Rails Guides

如果你想要的网址看起来像/signup您可以添加一个名为路线吧:

# Users 
get '/signup', to: 'lead_magnets#new' 
post '/signup', to: 'lead_magnets#create' 

然后在你的注册表格,你需要明确地引用新的注册路径:

<?= form_for @user, url: signup_path do |f| ?> 

生成的HTML看起来应该像

<form class="new_user" id="new_user" action="/signup" method="post"> 
0

原因是因为当您提交表单时,您是从new视图中将其提交给某个操作。该表单提交到该动作有一个路径,你可以看到的路径是通过打字什么:

rake routes 
在控制台

并搜索创建行动。如果在创建操作中验证失败,请致电render 'new'

当您渲染模板时,正在渲染的页面的url将是呈现模板的控制器操作的url /路径。

就你的情况而言,无论你有什么动作render 'new'将成为你的模板渲染后决定url的行为。

2

在Rails REST约定中,您使用不同的URI来显示表单以创建资源,并使用您要发布的表单action属性。

比方说你有:

resources :pets 

这给我们:

GET /pets/new => pets#new 
POST /pets  => pets#create 

然后我们有一个典型形式:

# posts to /pets 
<%= form_for(@pet) do |f| %> 
    <%= f.label :name %> 
    <%= f.text_field :name %> 
    <%= f.submit %> 
<% end %> 

而且磨机控制器的运行:

class PetsController < ApplicationController 
    def new 
    @pet = Pet.new 
    end 

    def create 
    @pet = Pet.new(pet_params) 
    if @pet.save 
     redirect_to @pet 
    else 
     render :new 
    end 
    end 

    # ... 
end 

因此,当用户访问/pets/new并填写表单时,如果表单无效,则浏览器url应该读取/pets。这是预期的行为 - 发布到不同的URL避免了无数的缓存和历史相关的问题。

从宁静的角度来看,它也正确 - 您不再查看新的操作 - 您正在查看尝试创建资源的结果。前者是幂等的 - 后者不是。

您需要认识到行render :newrender template: 'pets/new'的缩写。它不重定向,它不会调用控制器中的new操作。它只是呈现模板并将其作为对当前请求的响应返回。

相关问题