16

私はこれでしばらく苦労してきました。システムに 2 人のユーザーがいる Rails4/Devise 3.1 アプリがあります。

  1. 卒業生
  2. 雇用主

:profileそして、ポリモーフィックアソシエーションを介して卒業生または雇用主になることができる 1 つのデバイス ユーザー。卒業生はパス経由でサインアップし/graduate/sign_up、雇用主は/employer/sign_upパス経由で両方とも同じ/views/devise/registrations/new.html.erbビューにルーティングします (サインアップフォームはほとんど同じであるため、電子メールとパスワード)。検証エラーが発生した場合を除いて、すべて正常に動作し、RegistrationsController#create.respond_with resource常に両方のユーザー タイプを/usersパスにリダイレクトし、元の場所 (/graduate/sign_upまたは/employer/sign_upそれぞれ) にリダイレクトする必要があります。に置き換えようとrespond_withしましredirect_toたが、リソース オブジェクトが失われ、関連するエラー メッセージが表示されます。これをどのように行うことができるかについてのアイデアはありますか?

これらは私のモデルです:

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 < Devise::RegistrationsController

  def create
    build_resource sign_up_params

    user_type = params[:user][:user_type]
    # This gets set to either 'Graduate' or 'Employer'
    child_class_name = user_type.downcase.camelize
    resource.profile = child_class_name.constantize.new

    if resource.save
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_navigational_format?
        sign_up(resource_name, resource)
        respond_with resource, :location => 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

登録ビュー (卒業生と雇用者の両方で同じ):

<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <div><%= f.label :email %><br />
  <%= f.email_field :email, :autofocus => true %></div>

  <div><%= f.label :password %><br />
  <%= f.password_field :password %></div>

  <div><%= f.label :password_confirmation %><br />
  <%= f.password_field :password_confirmation %></div>
  <%= hidden_field resource_name, :user_type, value: params[:user][:user_type] %>

  <div><%= f.submit "Sign up" %></div>
<% end %>

<%= render "devise/shared/links" %>

これらは私のルートです:

 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 ルートの出力;

$ 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      /   
4

3 に答える 3

6

どうやら:location、この場合は #index という名前の既存のテンプレートがある場合、パラメーターは無視されます。リソースにエラーがある場合、Devise が #index または #show にリダイレクトする理由はまだわかりません。

詳細がわかり次第、この回答を更新します。

于 2013-12-13T16:23:26.157 に答える
3

を呼び出すrespond_withと、そのリソースのデフォルト アクションがレンダリングされます。これがindexアクション (/users/) であり、リダイレクトの原因であると私は信じています。

あなたがやりたいことは、new代わりにアクションをレンダリングすることだと思います。次のことを試してください。

if resource.save
  ...
else
  clean_up_passwords(resource)
  render :action => 'new'
end
于 2014-06-18T15:04:25.227 に答える
0

Respond_with の場合、html レスポンスの場合 - リクエスト メソッドが get の場合、例外が発生しますが、post などの他のリクエストの場合、レスポンスはリソースに検証エラーがあるかどうかによって異なります (つまり、保存しようとしたと仮定します)。たとえば create アクションによるリソース) -

エラーがない場合、つまりリソー​​スが正常に保存された場合、応答はリソース、つまりその show アクションにリダイレクトされます。

検証エラーがある場合、応答はデフォルト アクションをレンダリングします。これは、ポスト リクエストの場合は :new、パッチまたはプットの場合は :edit です。

ソース: http://apidock.com/rails/v4.1.8/ActionController/MimeResponds/respond_with

あなたの場合、render 'view_path'in place of respond_withblock のようなものが機能するはずです。

于 2017-03-22T06:54:24.447 に答える