Luhn算法的Ruby on Rails控制器和视图

fjnneemd  于 2023-04-11  发布在  Ruby
关注(0)|答案(2)|浏览(77)

我有一个问题,从视图中的字段使用模型的方法。我知道我应该从控制器中使用它,但我不知道如何做到这一点。
到目前为止,我已经创建了一个包含值的信用卡脚手架:number:int,type:string,validation:字符串
这是我的模型和方法
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
我应用了第一个方法,然后是第二个方法,返回一个字符串1234567890123[card_number]//卡的类型//有效/无效
到目前为止,当我使用我的方法时,我得到了关于我的方法被识别的事实的不同错误。

更新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

目前,它几乎是平原,因为它是脚手架后。我试图使它的工作使用回调,但我这样做,作为一个孩子在雾中。

mwecs4sa

mwecs4sa1#

首先,你的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
fruv7luv

fruv7luv2#

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

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

然后,如果新操作无效,它将呈现新操作,您只需向用户显示错误。
我将把代码其余部分的重构/更改留给您。

相关问题