Rails 4如何在出错时覆盖设计响应路径

我一直在努力争取这个。 我有一个Rails4 / Devise 3.1应用程序,系统中有两个用户:

  1. gradle生
  2. 雇主

和一个设计用户可以通过多态:profile关联成为研究生或雇主。 我有gradle生通过/graduate/sign_up路径和雇主通过/employer/sign_up路径注册两个路由到相同的/views/devise/registrations/new.html.erb视图(因为他们的注册表格几乎相同 -电子邮件和密码)。 一切正常,除非有validation错误, RegistrationsController#create.respond_with resource总是将两个用户类型重定向到/users路径,我需要将它们重定向回原来的位置,例如/graduate/sign_up/employer/sign_up分别是/employer/sign_up 。 我尝试用redirect_to替换respond_with ,但最终我丢失了带有相关错误消息的资源对象。 谁知道如何做到这一点?

这些是我的模特:

 class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable belongs_to :profile, polymorphic: true end class Graduate < ActiveRecord::Base has_one :user, as: :profile end class Employer < ActiveRecord::Base has_one :user, as: :profile end 

注册管理员:

 class RegistrationsController  after_sign_up_path_for(resource) else set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format? expire_session_data_after_sign_in! respond_with resource, :location => after_inactive_sign_up_path_for(resource) end else clean_up_passwords(resource) respond_with resource end end end 

注册视图(同样适用于gradle生和雇主):

 

Sign up


true %>


这些是我的路线:

  devise_for :users, :controllers => { :registrations => 'registrations' } devise_scope :user do match 'graduate/sign_up', to: 'registrations#new', user: { user_type: 'graduate' }, via: [:get] match 'employer/sign_up', to: 'registrations#new', user: { user_type: 'employer' }, via: [:get] end root to: 'home#index' 

耙路线的输出;

 $ rake routes Prefix Verb URI Pattern Controller#Action new_user_session GET /users/sign_in(.:format) devise/sessions#new user_session POST /users/sign_in(.:format) devise/sessions#create destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy user_password POST /users/password(.:format) devise/passwords#create new_user_password GET /users/password/new(.:format) devise/passwords#new edit_user_password GET /users/password/edit(.:format) devise/passwords#edit PATCH /users/password(.:format) devise/passwords#update PUT /users/password(.:format) devise/passwords#update cancel_user_registration GET /users/cancel(.:format) registrations#cancel user_registration POST /users(.:format) registrations#create new_user_registration GET /users/sign_up(.:format) registrations#new edit_user_registration GET /users/edit(.:format) registrations#edit PATCH /users(.:format) registrations#update PUT /users(.:format) registrations#update DELETE /users(.:format) registrations#destroy graduate_sign_up GET /graduate/sign_up(.:format) registrations#new {:user=>{:user_type=>"graduate"}} employer_sign_up GET /employer/sign_up(.:format) registrations#new {:user=>{:user_type=>"employer"}} root GET / 

显然 ,如果你有一个现有的模板,就会忽略:location参数,在这种情况下,#index。 我仍然不明白为什么当资源有错误时,Devise会重定向到#index或#show。

当我发现更多时,我会更新这个答案。

调用respond_with将呈现该资源的默认操作。 我相信这是index操作(/ users /),因此是重定向的原因。

我想你想要做的就是渲染new动作。 请尝试以下方法:

 if resource.save ... else clean_up_passwords(resource) render :action => 'new' end 

在respond_with的情况下,对于html响应 – 如果请求方法是get,则引发exception但是对于其他请求(例如发布响应)取决于资源是否有任何validation错误(即假设已尝试保存)资源,例如通过创建动作) –

如果没有错误,即资源已成功保存,则响应重定向到资源,即其show动作。

如果存在validation错误,则响应将呈现默认操作,即:对于发布请求为new,或者为patch或put进行编辑。

来源: http : //apidock.com/rails/v4.1.8/ActionController/MimeResponds/respond_with

对于你的情况, render 'view_path'代替respond_with块应该可以工作。