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 留给您。
我在视图中的字段上使用模型中的方法时遇到问题。 我知道我应该从控制器使用它,但我不知道该怎么做。
到目前为止,我已经为信用卡创建了一个脚手架,其值: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 留给您。