【问题标题】:How do I screen for integers that are too big in my Rails model?如何筛选 Rails 模型中太大的整数?
【发布时间】:2016-12-12 15:14:23
【问题描述】:

我正在使用带有 PostGres 9.5 的 Rails 4.2.7。我的 Rails 迁移中有这个专栏...

my_num               | integer                     | 

在我的模型中,我想筛选过大的数字并将它们设置为 nil。例如,我的模型上设置了数字“659722222222222”并导致以下错误

Error during processing: (RangeError) 659722222222222 is out of range for ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer with limit 4
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/type/integer.rb:45:in `ensure_in_range'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/type/integer.rb:23:in `type_cast_for_database'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/abstract/quoting.rb:13:in `quote'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:641:in `block (2 levels) in values_sql_for_columns_and_attributes'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:631:in `each'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:631:in `each_with_index'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:631:in `each'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:631:in `map'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:631:in `block in values_sql_for_columns_and_attributes'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:630:in `map'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:630:in `values_sql_for_columns_and_attributes'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:530:in `import_without_validations_or_callbacks'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:490:in `import_with_validations'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:417:in `import_helper'
/Users/davea/.rvm/gems/ruby-2.3.0/gems/activerecord-import-0.16.1/lib/activerecord-import/import.rb:331:in `import'
/Users/davea/Documents/workspace//app/services/abstract_import_service.rb:161:in `block in save_my_object__time_results'

我不想保存模型,而是将字段设置为 nil,仅当它设置为对 PostGres SQL 来说太大的整数值时。我该怎么做?

注意,我不想更改 PostGres 列的列类型。你没想到这会那么容易,是吗?

【问题讨论】:

    标签: ruby-on-rails postgresql ruby-on-rails-4 model integer


    【解决方案1】:

    2147483647 是 Postgres 中整数类型的最大值。

    before_save :is_too_big
    
    def is_too_big
      if my_num > 2147483647
        # do something
      end
    end
    

    如果您不想在代码中添加幻数,我建议您在发生超出范围时捕获异常:

    # somewhere in the code
    u = User.new(my_num: 2147483648)
    begin
     u.save
    rescue RangeError => e
     u.my_num = nil
     u.save
    end
    

    【讨论】:

    • 是否有代表 2147483647 的常数?我记得在我的代码中输入幻数时,我在计算机科学课上丢了分。
    • 这没有常数。 integer 类型是它是一个 4 字节有符号整数。从-2147483648+2147483647
    • @Dave 你可以推导出这个数字,但它仍然神奇地与知道 Postgres 的最大值是多少有关。在 Ruby 中,您可以使用((2**32)/2)-1 来获得这个最大值(4 个字节是 32 位,但一半的数字是负数)。
    【解决方案2】:

    添加验证前事件

    before_validation :ensure_my_num_ok
    

    如果不好就设置值

    def ensure_my_num_ok
      self.my_num = nil  if my_num > 100000000
    end
    

    【讨论】:

      猜你喜欢
      • 2018-12-24
      • 1970-01-01
      • 2016-06-20
      • 2018-03-04
      • 2015-01-26
      • 1970-01-01
      • 2013-10-03
      • 1970-01-01
      • 2010-09-21
      相关资源
      最近更新 更多