【问题标题】:Ruby: Verifying if the given user input is a numberRuby:验证给定的用户输入是否是数字
【发布时间】:2015-10-28 05:51:30
【问题描述】:

我想检查基本上是用户输入的变量是否是 10 位电话号码。

有 2 组验证: - 如果 num 小于 10 位,则提示 msg - 如果 num 是字符串而不是整数

@phone = params[:phone_num]
    puts "phone_num: #{@phone}"
    if @phone.is_a? Integer 
      puts "phone_num is int"
      if @phone.to_s.length == 10
        puts "10 digit"
        perform(@phone)
        @output = "Valid Number, will receive a call"
      end
    else 
      puts "Wont be calling"
      @output = "The number is invalid"
    end

无论我在文本框中输入什么,我得到的输出总是The number is invalid。有许多堆栈溢出回答处理不同的问题,但想知道为什么我的代码不起作用。

【问题讨论】:

标签: ruby-on-rails ruby validation int


【解决方案1】:

对此有标准验证 (length) 和 (numericality):

#app/models/user.rb
class User < ActiveRecord::Base
   validates :phone_num, length: { is: 10 }, numericality: { only_integer: true }
end

这种类型的验证属于模型。


备注

您的控制器将如下所示:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def create
      @user = User.new user_params
      @user.save #-> validations handled by model
   end
end

有一个原则叫做fat model, skinny controller——你应该在你的模型中加入“数据”逻辑。

这样做的原因是为了从控制器中删除低效的代码。

它使您能够委派您的大部分逻辑到 Rails 核心助手(例如validations),而不是在前端调用您自己的大量代码(像您'正在做)。

每次运行 Rails 应用程序时,各种类(控制器和模型)都会加载到内存中。除了所有的 Rails 类(ActiveRecord 等),你的控制器和模型也必须被加载。

任何额外的代码会导致bloat,使您的应用程序出错且无法使用。最好的开发人员知道什么时候使用他们自己的代码,什么时候委托给 Rails。这个例子完美地展示了何时委派。

【讨论】:

  • 谢谢里奇。这是一个很好的例子,在我的场景中没有模型,我会怎么做。我不想存储任何东西。尽管存储可能非常有意义。但是如果没有模型,想知道另一个最佳实践
  • 通过模型代码,我想查看不同类型的消息。你的例子怎么可能,因为验证只发生在模型中?
  • @fscore 你仍然可以使用验证而不持久化到数据库,你可以创建一个不继承任何东西的类。
  • 在一个新的类中包含一堆功能和逻辑是高级的东西,并且在类似railscasts.com/episodes/…
  • 另外,如果您希望人们能够输入像(710) 123-3456 这样的电话号码,那么验证数字将不起作用;你会想在写作时预处理数字 - 也许def number=(val); write_attribute :val, val.gsub! /\D/, ''; end; - 如果你不使用数据库,这不相关,但我就是这样做的!
【解决方案2】:

我得到的输出总是 The number is invalid 不管我做什么 在文本框中输入。

您的代码总是回退到else 部分的原因是来自params 的值将始终是字符串。所以params[:phone_num] 的值是一个字符串。所以你的代码在这里失败了if @phone.is_a? Integer。相反,您需要将其更改为 params[:phone_num].to_i

@phone = params[:phone_num].to_i
puts "phone_num: #{@phone}"
  if @phone.is_a? Integer 
    puts "phone_num is int"
    if @phone.to_s.length == 10
      puts "10 digit"
      perform(@phone)
      @output = "Valid Number, will receive a call"
    end
  else 
    puts "Wont be calling"
    @output = "The number is invalid"
  end

注意:

是的。这是执行验证的糟糕方法。我只是在回答OP的问题。

【讨论】:

【解决方案3】:

看看这个 - A comprehensive regex for phone number validation - 如何确定一个字符串看起来像一个电话号码。有一个非常复杂的正则表达式,因为人们输入电话号码的形式多种多样!

我个人不喜欢超级复杂的正则表达式,但这几乎就是它们的发明目的。所以这是当你想弄清楚什么样的表格是可以接受的,写一些测试,并根据上面的大量链接让你的代码通过你的接受!

编辑:您的代码在很多地方都是错误的; params 已经是一个字符串,所以试试这个!记住你的嵌套 if/else/end。

@phone = params[:phone_num]
if @phone =~ /\A\d+\Z/ # replace with better regex
  # this just means "string is all numbers"
  puts "phone_num is int"
  if @phone.length == 10
    puts "10 digit"
    perform(@phone)
    @output = "Valid Number, will receive a call"
  else
    puts "Number length wrong, #{@phone.length}"
  end
else 
  puts "Wont be calling, not a number: #{@phone.inspect}"
  @output = "The number is invalid"
end

【讨论】:

    猜你喜欢
    • 2018-08-18
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2020-04-18
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2016-10-05
    相关资源
    最近更新 更多