Ruby Rails 控制器和 Luhn 算法视图

Ruby on Rails controller and view for Luhn Algorithm

我在视图中的字段上使用模型中的方法时遇到问题。 我知道我应该从控制器使用它,但我不知道该怎么做。

到目前为止,我已经为信用卡创建了一个脚手架,其值:number:int, type:string, validation: string

这是我的模型和方法

credit_card.rb

class CreditCard < ActiveRecord::Base
    validates :number, presence:true, length: { maximum: 16}

#Methods for luhn validation

#First checking the type of card
    def self.find_type(credit_card)
        # Making sure that the card number is passed as a string
        credit_card = credit_card.to_s
        # Set of statements to return the appropriate card type
        # Firstly the code checks the cards's length
        # Secondly regexp, returns 0 which signals validation
        return "AMEX"   if credit_card.length == 15 && (credit_card =~ /^(34|37)/) == 0
        return "Discover"   if credit_card.length == 16 && (credit_card =~ /^6011/) == 0
        return "MasterCard" if credit_card.length == 16 && (credit_card =~ /^(5[1-5])/) == 0
        return "VISA"   if [13,16].include?(credit_card.length) && (credit_card =~ /^4/) == 0
        return "Unknown"
    end

#Secondly applying the Luhn algorithm on the number to check is the number valid or not
def self.luhn(cc_number)
    result = 0
    nums = cc_number.to_s.split("")
    nums.each_with_index do |item, index|
      if index.even?
        result += item.to_i * 2 >9 ? item.to_i*2-9 : item.to_i*2
      else
        result +=item.to_i
        end
    end
    if (result % 10) == 0
      return "valid"
    else
      return "invalid"
    end
  end

end

现在我想在发卡之前应用这些方法 所以例如我在文本字段中输入一个数字 card_number: 1234567890123

我应用了第一种方法,然后是第二种方法。 而我return一个字符串1234567890123[card_number]//卡的类型//valid/invalid

到目前为止,当我使用我的方法时,我遇到了不同的错误 关于我的方法无法识别的事实。

我知道我的问题似乎很简单,但我现在已经忙了 2 天了。

感谢您的帮助

更新 1

这是我当前的控制器

class CreditCardsController < ApplicationController
  before_action :set_credit_card, only: [:show, :edit, :update, :destroy]
  attr_accessor :number

  def index
    @credit_cards = CreditCard.all
  end

  def show
  end

  def new
    @credit_card = CreditCard.new
  end

  def create
    @credit_card = CreditCard.new(

    respond_to do |format|
      if @credit_card.save
        format.html { redirect_to @credit_card, notice: 'Credit card was successfully created.' }
        format.json { render :show, status: :created, location: @credit_card }
      else
        format.html { render :new }
        format.json { render json: @credit_card.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @credit_card.destroy
    respond_to do |format|
      format.html { redirect_to credit_cards_url, notice: 'Credit card was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_credit_card
      @credit_card = CreditCard.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def credit_card_params
      params.require(:credit_card).permit(:number, :type, :validation)
    end
end

目前它几乎和搭建脚手架后一样平整。 我试图通过使用回调来使其工作,但我正在这样做 child in fog

首先,您的 luhn 方法实现逻辑看起来不正确!刚刚纠正了这段代码: 您可以通过调用 CreditCard.luhn("61789372994") 来交叉验证这一点 请检查:http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers

 def self.luhn(cc_number)
    result = 0
    nums = cc_number.to_s.chars.map(&:to_i)

    nums.each_with_index do |item, index|
      if index.odd?
        item *= 2 
        result +=  item > 9 ? item.to_s.chars.map(&:to_i).inject(:+) : item
      else
        result +=item
      end
    end

   return "valid" if (result % 10) == 0
   return 'invalid'
  end

接下来要调用它,您只需使用以下代码:

Creditcard.luhn("61789372994") #will return "valid"

接下来,在您的情况下,您可能正在尝试具有以下功能: - 您要验证卡号,如果有效则保存记录 - 如果它是无效的,则不要存储卡并为此提供有效的错误消息。 在这种情况下,您可以采用以下方法:

 #credit_card.rb
Class CreditCard < ActiveRecord::Base 
 #custom  validations.
 validate :valid_card_number? 
  validate :valid_card_type?

  private
  def valid_card_number?
    cc_number = self.number #see your controller#credit_card_params
    #above luhn method body goes here. 
     if (result % 10) == 0  #result you will get from the luhn method.
      errors.add(:number, 'Sorry, an invalid cardNumber Entered')
     end
  end

  def valid_card_type?
   #like valid_card_number? implement this one as well. 
  end
end

现在在控制器中,当我们尝试保存那些信用卡记录时,上述验证将自动执行。

 #credit_cards_controller.rb
    def create
      @credit_card = CreditCard.new(credit_card_params)
      respond_to do |format|
        if @credit_card.save
          format.html { redirect_to @credit_card, notice: 'Credit card was successfully created.' }
          format.json { render :show, status: :created, location: @credit_card }
        else
          format.html { render :new }
          format.json { render json: @credit_card.errors, status: :unprocessable_entity }
        end
      end

因为我不确定你在哪里调用你的方法,或者你最终想要做什么我不确定这是正确的但对我来说这些方法不应该 class 方法。

class CreditCard < ActiveRecord::Base
  before_validation :set_type
  validates :number, presence:true, length: { maximum: 16}
  validate :check_luhn

  #Methods for luhn validation

  #First checking the type of card
  def set_type
    # Making sure that the card number is passed as a string
    credit_card_number = number.to_s
    # Set of statements to return the appropriate card type
    # Firstly the code checks the cards's length
    # Secondly regexp, returns 0 which signals validation
    self.type = 'Amex' if credit_card.length == 15 && (credit_card =~ /^(34|37)/) == 0
    self.type = 'Discover' if credit_card.length == 16 && (credit_card =~ /^6011/) == 0
    self.type = 'MasterCard' if credit_card.length == 16 && (credit_card =~ /^(5[1-5])/) == 0
    self.type = 'VISA'   if [13,16].include?(credit_card.length) && (credit_card =~ /^4/) == 0
    self.type = 'Unknown'
  end

  #Secondly applying the Luhn algorithm on the number to check is the number valid or not

  def check_luhn
    result = 0
    nums = number.to_s.split("")
    nums.each_with_index do |item, index|
      if index.even?
        result += item.to_i * 2 >9 ? item.to_i*2-9 : item.to_i*2
      else
        result +=item.to_i
        end
    end
    if (result % 10) != 0
      errors.add(:number, 'is not a valid credit card number')
    end
  end    
end

所以我根据信用卡号设置了验证前的类型,并让luhn检查验证,在检查失败时添加错误。

这意味着在您的控制器中您可以执行标准 rails 操作:

def create
  @credit_card = CreditCard.new(credit_card_params)

  respond_to do |format|
    if @credit_card.save
      format.html { redirect_to @credit_card, notice: 'Credit card was successfully created.' }
      format.json { render :show, status: :created, location: @credit_card }
    else
      format.html { render :new }
      format.json { render json: @credit_card.errors, status: :unprocessable_entity }
    end
  end
end

如果新操作无效,它将呈现新操作,您只需要向用户显示错误。

我会将其余代码的任何 refactoring/changes 留给您。