简体   繁体   中英

Ruby: How to reference model variables in a controller?

Currently, a user can create multiple accounts and use the same paypal_email for each account.

I'm trying to restrict each user to one unique paypal_email. I don't want to use :uniqueness => true because there are some instances where admin can allow a user to have more than 1 account (and therefore sharing 1 paypal_email).

To restrict each user to 1 unique paypal_email I've setup a field in Users model called :warning. If the :warning is set to "Accepted" then there should be no duplicates in the Users model of that paypal_email. If the :warning is "Banned" then that submitted paypal_email should be rejected. When :warning is "Warned" its ignored.

The ReviewPayments controller verifies the paypal_email when user submits their paypal_email (duplicate paypal_email field in the ReviewPayments model, which, if valid, is copied into the Users model). The ReviewsPayment model belongs to the Reviews model, and the Reviews model belongs to the Users model. (ex. ReviewsPayment << Reviews << Users). So I should be able to reference the Users model fields (like :paypal_email and :warning) in the ReviewsPayment controller, right? I don't think it's working. My code from the controller is below:

In testing (staging site), when I submit a banned paypal_email (ie. :warning == "Banned") the duplicate_paypal? method returned true rather than the banned_paypal? method. In fact, when I input any paypal_email that's already in the User database it gets rejected through duplicate_paypal method. If I put in a completely new paypal_email it passes. It seems the .where conditions are not setup correctly. Which means I'm not referencing the User model correctly.

Help?

class My::ReviewPaymentsController < ApplicationController
  before_filter :require_login
  before_filter :load_review
  before_filter :new_payment

  def new
    @payment.paypal_email = current_user.paypal_email
  end

    def create
    @payment.payment_type = "PayPal"
    @payment.paypal_email = params[:review_payment][:paypal_email]


    # if paypal_email is not a duplicate then check to ensure
    # it's not a banned user's paypal account
    if :duplicate_paypal?
      @payment.errors.add(:paypal_email, "This Paypal account is associated with another registered user.  
      Please provide your own Paypal account.")
      render :new     
    elsif :banned_paypal?
      @payment.errors.add(:paypal_email, "This Paypal account is disabled.  
      Please provide another Paypal account.")
      render :new
    elsif @payment.save && @review.start_audit
      flash[:success] = "Thank you for your review! You will receive your payment shortly."
      redirect_to root_path
    else
      render :new
    end
  end

  def duplicate_paypal
    @countdupe = 0
    @currentuserid = current_user.reviews.find params[:user_id]
    @countdupe = User.where(:warning == "Accepted" && :id != @currentuserid).find_all_by_paypal_email(current_user.paypal_email).count 
    @countdupe > 0
  end

def banned_paypal
        @countdupe = 0
        @countdupe = User.where(:warning == "Banned").find_all_by_paypal_email(current_user.paypal_email).count 
        @countdupe != 0
      end

  protected

  def load_review
    @review = current_user.reviews.find params[:review_id]
    @manuscript = @review.manuscript
  end

  def new_payment
    @payment = ReviewPayment.new
    @payment.review = @review
    @payment.review_payment_amount = ReviewPayment::RewardAmount
  end
end

Add the validation in your model and check out following link:

http://edgeguides.rubyonrails.org/active_record_validations.html#using-a-string-with-if-and-unless

That will solve your problems immediately. To get the main idea:

class User < ActiveRecord::Base
  validates :paypal_email, uniqueness: true, if: Proc.new { |u| u.warning == "Banned" }
end

It's better to use here conditional validations http://edgeguides.rubyonrails.org/active_record_validations.html#conditional-validation

In your model you can write this:

validates :paypal_email, uniqueness: true, if: :warning?

And use warning attribute as a boolean value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM