【问题标题】:Override method from Quoting module引用模块中的覆盖方法
【发布时间】:2014-06-04 05:03:44
【问题描述】:

我想从 C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-4.0.2/lib/ 覆盖方法 type_cast(value, column) active_record/connection_adapters/abstract/quoting.rb

module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module Quoting

  # Cast a +value+ to a type that the database understands. For example,
  # SQLite does not understand dates, so this method will convert a Date
  # to a String.
  def type_cast(value, column)
    return value.id if value.respond_to?(:quoted_id)

    case value
    when String, ActiveSupport::Multibyte::Chars
      value = value.to_s
      return value unless column

      case column.type
      when :binary then value
      when :integer then value.to_i
      when :float then value.to_f
      else
        value
      end

    when true, false
      if column && column.type == :integer
        value ? 1 : 0
      else
        value ? 't' : 'f'
      end
      # BigDecimals need to be put in a non-normalized form and quoted.
    when nil        then nil
    when BigDecimal then value.to_s('F')
    when Numeric    then value
    when Date, Time then quoted_date(value)
    when Symbol     then value.to_s
    else
      to_type = column ? " to #{column.type}" : ""
      raise TypeError, "can't cast #{value.class}#{to_type}"
    end
  end
    end
  end
end

行问题

when true, false
  if column && column.type == :integer
    value ? 1 : 0
  else
    value ? 't' : 'f'

我想得到

when true, false
  value ? 1 : 0

在 C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-4.0.2/lib/ active_record/connection_adapters/abstract_adapter.rb 类 AbstractAdapter 包括引用。

module ActiveRecord
  module ConnectionAdapters # :nodoc:
    extend ActiveSupport::Autoload

    ...

    class AbstractAdapter
      include Quoting

     ...
    end
  end
end

并且SQLite3Adapter类继承AbstractAdapter: (C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-4.0.2/lib/active_record/connection_adapters/sqlite3_adapter.rb)

class SQLite3Adapter < AbstractAdapter
  def type_cast(value, column) # :nodoc:
    return value.to_f if BigDecimal === value
    return super unless String === value
    return super unless column && value

    value = super
    if column.type == :string && value.encoding == Encoding::ASCII_8BIT
      logger.error "Binary data inserted for `string` type on column `#{column.name}`" if logger
      value = value.encode Encoding::UTF_8
    end
    value
  end
end

如何覆盖方法 type_cast(value, column)?我尝试这样的事情

# config/initializers/sqlite3_adapter_extension.rb

module ActiveRecord
  module ConnectionAdapters
    class SQLite3Adapter < AbstractAdapter

      def type_cast(value, column) # :nodoc:
        case value
        when true, false
          value ? 1 : 0
        end
      end
    end
  end
end

但它可以预见的行不通。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4


    【解决方案1】:

    我不确定您到底在做什么,但是如果您想为特定模型执行此操作,您可以在模型类本身中覆盖此方法,但如果您确定要为所有应用程序覆盖它您只需要在 config/initializers 中创建一个新的 .rb 文件并添加这样的代码

     module ActiveRecord
      module ConnectionAdapters # :nodoc:
        module Quoting
          def type_cast(value, column) # :nodoc:
            case value
            when true, false
              value ? 1 : 0
            end
          end
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      • 2016-12-06
      • 2021-01-06
      • 1970-01-01
      • 2012-06-05
      • 2010-10-09
      相关资源
      最近更新 更多