1

サブドメイン ala railscast #388 を使用してマルチテナント アプリを構築しようとしています。認証にdeviseを使用しているため、問題を引き起こしている別のねじれが追加されました。別のサブドメイン (アカウント) で既に作成されている電子メールを使用して新しいユーザーを追加しようとすると、次のエラーが発生します。

ActiveRecord::StatementInvalid in RegistrationsController#create

SQLite3::ConstraintException: constraint failed: INSERT INTO "users" ("account_id", "created_at", "current_sign_in_at", "current_sign_in_ip", "email", "encrypted_password", "last_sign_in_at", "last_sign_in_ip", "remember_created_at", "reset_password_sent_at", "reset_password_token", "sign_in_count", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

新しいユーザーの電子メールがデータベースのどこにも存在しない場合、新しいユーザーの追加はうまく機能するため、電子メールの検証にスコープを追加する方法に問題があると想定しています。:validatable デバイス モジュールを無効にし、検証をユーザー モデルに追加しました。

class User < ActiveRecord::Base

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable


  attr_accessible :email, :password, :password_confirmation, :remember_me
  belongs_to :account


  validates_uniqueness_of :email, :scope => :account_id, :case_sensitive => false, :allow_blank => true, :if => :email_changed?
  validates_format_of :email, :with => Devise.email_regexp, :allow_blank => true, :if => :email_changed?
  validates_presence_of :password, :on=>:create
  validates_confirmation_of :password, :on=>:create
  validates_length_of :password, :within => Devise.password_length, :allow_blank => true

  default_scope { where(account_id: Account.current_id) }

end

class Account < ActiveRecord::Base
  attr_accessible :name, :subdomain
  has_many :clients, :dependent => :destroy
  has_many :users
  cattr_accessor :current_id

end

class ApplicationController < ActionController::Base
  protect_from_forgery

  around_filter :scope_current_account

private

  def current_account
    Account.find_by_subdomain! request.subdomain
  end
  helper_method :current_account

  def scope_current_account
    Account.current_id = current_account.id
    yield
  ensure
    Account.current_id = nil
  end

end

ありがとう

4

1 に答える 1