2017-12-13 4 views
1

私はクライアント用のモデルを持っています。新しいクライアントを作成すると、クライアント電子メールでUserが作成されます。アフィリエイトを作成すると同じことが起こります。クライアントとユーザの両方でemailのvalidates_uniqueness_を同時に使用できますか?2つのモデルの電子メールをレールで一度にvalidates_uniqueness_ofできますか?

また、同じ電子メールを持つユーザがいるかどうかを確認する前に、どうしたらよいですか?

私はこれを試してみましたが、それは

validate :uniqueness_of_user 

    private 

    def uniqueness_of_user 
    @user = User.find_by_email(:email) 
    if @user.present? 
     errors.add(:email, "Bang!") 
    end 
    end 

編集は動作しません:

これはコントローラです:

def create 
    @affiliate = Affiliate.new(affiliate_params) 
    respond_to do |format| 
     if verify_recaptcha(model: @affiliate) && @affiliate.save 
     @user = User.create!(user_parameter) 
     pplicationMailer.confirmation(@affiliate).deliver_now 

     format.html {redirect_to :back, notice: 'Thanks for your submission, we will be in touch shortly. Check your email for your affiliate number and password.' } 
     format.json { render :show, status: :created, location: @affiliate } 
     else 
     format.html { render :signup, layout: "sign-ups" } 
     format.json { render json: @affiliate.errors, status: :unprocessable_entity } 
     end 
    end 
    end 
+0

一意性のバリデーターがあります。あなた自身で書く必要はありません。また、ユーザーがクライアントを介してのみ作成できる場合、それを強制する必要もありません(とにかく傷つくことはありません)。検証は 'validates:email、uniqueness:true'のようになります – Maxence

+0

一部のユーザが存在する場合、またはクライアントとは異なる方法で作成することができます。私はあなたがクライアントを作成する前に(そして両方のモデルで一意性を強制する前に)この電子メールを持っていないことをコントローラにチェックインすることをお勧めします。また、クライアントとユーザの作成を 'transaction'にカプセル化して、同じブロックで行います。 (例えば、クライアントコントローラのアクションを作成する場合) – Maxence

+0

これは、クライアントまたはアフィリエイトの内部でのみ検証されます。クライアントとアフィリエイトの両方がユーザーを作成します。私の問題は、一部のアフィリエイトがクライアントに対して同じ電子メールを使用しようとし、ユーザーが既に存在するためにクライアントが保存されますが、ユーザーが既に存在するためにエラーが発生することです。したがって、ユーザーまたはアフィリエイトが作成される前に、そのメールのユーザーが存在するかどうかを確認する必要があります。 – Allan

答えて

0

チェックこの場合についての良い記事のコードの下に、コードをコピーしましたが、完全な説明のために記事のリンクを確認してください:

# app/models/concerns/validate_identifier_uniqueness_across_models.rb 
module ValidateIdentifierUniquenessAcrossModels 
    extend ActiveSupport::Concern 

    @@included_classes = [] 

    included do 
    @@included_classes << self 
    validate :identifier_unique_across_all_models 
    end 

    private 

    def identifier_unique_across_all_models 
    return if self.identifier.blank? 
    @@included_classes.each do |klass| 
     scope = klass.where(identifier: self.identifier) 
     if self.persisted? && klass == self.class 
     scope = scope.where('id != ?', self.id) 
     end 
     if scope.any? 
     self.errors.add :identifier, 'is already taken' 
     break 
     end 
    end 
    end 
end 

# app/models/product.rb 
class Product < ActiveRecord::Base 
    include ValidateIdentifierUniquenessAcrossModels 
end 

# app/models/category.rb 
class Category < ActiveRecord::Base 
    include ValidateIdentifierUniquenessAcrossModels 
end 

参考:
https://www.krautcomputing.com/blog/2015/03/29/rails-validate-uniqueness-across-models/

UPDATE:
ソリューション1データを同時に保存されている場合は、最善のことは、以下のようにトランザクションにまとめて保存されたデータを含めることです。

def create 
    email_validity 
    @affiliate = Affiliate.new(affiliate_params) 
    respond_to do |format| 
     ActiveRecord::Base.transaction do 
     if verify_recaptcha(model: @affiliate) && @affiliate.save 

     @user = User.create!(user_parameter) 
     if @user.valid? 
     ApplicationMailer.confirmation(@affiliate).deliver_now 

     format.html {redirect_to :back, notice: 'Thanks for your submission, we will be in touch shortly. Check your email for your affiliate number and password.'} 
     format.json {render :show, status: :created, location: @affiliate} 
     else 
     email_validity = false 
     raise ActiveRecord::Rollback 
     end 
    else 

     format.html {render :signup, layout: "sign-ups"} 
     format.json {render json: @affiliate.errors, status: :unprocessable_entity} 
    end 
    end 

    if email_validity == false 
    respond_to do |format| 
     format.html {redirect_to :back, notice: 'Sorry, email is in use!'} 
     # you can add your json return as you like 
    end 
    end 
end 

エンド

参考:
http://api.rubyonrails.org/classes/ActiveRecord/Rollback.html

ソリューション2関連会社への保存またはユーザーを作成する前に、お使いのコントローラで電子メールの存在のために両方のテーブルに確認してください。

+0

電子メール、および製品/カテゴリをクライアント/アフィリエイトに変更しようとしました。しかし、それは検証されません。それはまだアフィリエイトを作成し、私はユーザーの確認があるので、その電子メールを持つユーザーが既に存在すると言って私にページエラーを与える。 – Allan

+0

@Allan両方のデータをまとめて保存するコードを表示できますか? – Shiko

+0

作成アクションで質問を編集しました – Allan

0

email_addressを別のテーブルに保存することをお勧めします。住所:

class Address < ApplicationRecord 

    belongs_to :affilat 
    belongs_to :client 

    validates :email, 
       presence: true 
       uniqueness: true 
end 

ここで日付を保存するにはネストフォームを使用します。

関連する問題