ユーザー」モデルの工夫と複数
質問
rails 3.2とdevise 2.0を使っているのですが、Railsはかなり初心者なんです。
必要条件
以下を実現したい。
- 2つ以上のユーザーモデル(例:Member、Customer、Admin)を持っている。
- すべてのモデルがいくつかの必須フィールドを共有する (例: メールアドレスとパスワード)
- 各モデルは、いくつかのユニークなフィールドを持つことができます (例: Customerのみのcompany)
- いくつかのフィールドは共有されますが、同じバリデーションはありません (例: name は Customer では必須ですが、Member ではオプションです)
- すべてのフィールドは、登録プロセスで入力する必要があるため、フォームは異なります。
- ログインフォームは一意であるべきです。
可能な解決策
私はかなり長い間グーグルやStackOverflowで検索しましたが、私には何も正しいとは思えず(私はJavaの人です、すみません : )、今私はかなり混乱しています。2つのソリューションが出てきました。
単一のデバイスのユーザー
最も多い回答です。デフォルトのdevise Userを作成し、Member-->UserとCustomer-->Userの間のリレーションを作成するだけです。 ここで気になるのは、モデルごとにカスタマイズされた登録処理を実現するにはどうすればいいのか、ということです。
複数のデバイスのユーザー
これはカスタム登録プロセスを解決し、私には正しいように思えますが、ユニークなログインフォームがブロッカーです。SOに回答がありました( 工夫 - 2つのモデルからログイン )で、Devise::Models::Authenticatable.find_for_authentication(conditions)をオーバーライドすることを示唆しています。 それは複雑なようです(?)そして、私はrailsに新しいので、私はそれが動作することができるかどうかを知りたいのですが?
アドバイスありがとうございました。
どのように解決するのですか?
私はある方法を見つけ、今のところかなり満足しています。他の人のためにここに記述しておきます。
私は、単一の "user" クラスを使用しました。私の問題は、各擬似モデルに対してカスタマイズされた登録プロセスを実現することでした。
model/user.rb:
class User < ActiveRecord::Base
devise :confirmable,
:database_authenticatable,
:lockable,
:recoverable,
:registerable,
:rememberable,
:timeoutable,
:trackable,
:validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :role
as_enum :role, [:administrator, :client, :member]
validates_as_enum :role
## Rails 4+ for the above two lines
# enum role: [:administrator, :client, :member]
end
次に http://railscasts.com/episodes/217-multistep-forms と http://pastie.org/1084054 で、オーバーライドされたコントローラで2つの登録パスを持つことができます。
config/routes.rbを参照してください。
get 'users/sign_up' => 'users/registrations#new', :as => 'new_user_registration'
get 'clients/sign_up' => 'users/registrations#new_client', :as => 'new_client_registration'
post 'clients/sign_up' => 'users/registrations#create', :as => 'client_registration'
get 'members/sign_up' => 'users/registrations#new_member', :as => 'new_member_registration'
post 'members/sign_up' => 'users/registrations#create', :as => 'member_registration'
controllers/users/registrations_controller.rb:
各ステップで検証するフィールドを知るウィザードクラスを作りました。
class Users::RegistrationsController < Devise::RegistrationsController
# GET /resource/sign_up
def new
session[:user] ||= { }
@user = build_resource(session[:user])
@wizard = ClientRegistrationWizard.new(current_step)
respond_with @user
end
# GET /clients/sign_up
def new_client
session[:user] ||= { }
session[:user]['role'] = :client
@user = build_resource(session[:user])
@wizard = ClientRegistrationWizard.new(current_step)
render 'new_client'
end
# GET /members/sign_up
def new_member
# same
end
# POST /clients/sign_up
# POST /members/sign_up
def create
session[:user].deep_merge!(params[:user]) if params[:user]
@user = build_resource(session[:user])
@wizard = ClientRegistrationWizard.new(current_step)
if params[:previous_button]
@wizard.previous
elsif @user.valid?(@wizard)
if @wizard.last_step?
@user.save if @user.valid?
else
@wizard.next
end
end
session[:registration_current_step] = @wizard.current_step
if @user.new_record?
clean_up_passwords @user
render 'new_client'
else
#session[:registration_current_step] = nil
session[:user_params] = nil
if @user.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_in(:user, @user)
respond_with @user, :location => after_sign_up_path_for(@user)
else
set_flash_message :notice, :"signed_up_but_#{@user.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
respond_with @user, :location => after_inactive_sign_up_path_for(@user)
end
end
end
private
def current_step
if params[:wizard] && params[:wizard][:current_step]
return params[:wizard][:current_step]
end
return session[:registration_current_step]
end
end
と私の見解を述べました。
-
new.rb
-
new_client.rb
ウィザードのステップに従ってパーシャルを含む。-
_new_client_1.rb
-
_new_client_2.rb
-
-
new_member.rb
ウィザードのステップに従って、パーシャルを含む。-
_new_member_1.rb
-
_new_member_2.rb
-
関連
-
[解決済み】コレクションをDESCで並べる方法
-
[解決済み] 検索 vs 発見する by vs どこに
-
[解決済み] Railsです。gemを使った特定バージョンのライブラリのアンインストール
-
[解決済み] Rspec が私のモデルクラスを認識しない。初期化されていない定数エラー
-
[解決済み] 構文エラー "構文エラー、予期しない入力終了、keyword_endを期待 (SyntaxError)"
-
[解決済み] ActionController::RoutingError: 初期化されていない定数MicropostsController
-
[解決済み] 未初期化の定数 "コントローラ名"
-
[解決済み] エラーが発生しました。pgsqlをrailsで動作させようとすると、Peer authentication failed for user "postgres" と表示されます。
-
[解決済み] 別コントローラーでフォームを工夫する
-
[解決済み] RailsでDeviseのビューをカスタマイズする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】PG::ConnectionBad: fe_sendauth: パスワードが供給されない
-
[解決済み] Ruby on Railsのランナー
-
[解決済み] Errno::EACCESS: パーミッションが拒否された @ dir_s_mkdir
-
[解決済み] RVMでRubyのデフォルトバージョンを設定するには?
-
[解決済み] gemのアップデート後、"Asset was not declared to be precompiled in production "でテストが失敗する。
-
[解決済み] バリデーションなしで属性を更新する方法
-
[解決済み] rails consoleを起動するとRailsのイニシャライザーが呼ばれる?
-
[解決済み] 属性を割り当てる場合、引数としてハッシュを渡す必要がある
-
[解決済み] 構文エラー "構文エラー、予期しない入力終了、keyword_endを期待 (SyntaxError)"
-
[解決済み] RSpecとCucumberの違いは何ですか?[クローズド]