如何使这个代码只运行before_create

时间:2015-03-18 17:09:51

标签: ruby-on-rails

我正在尝试将用户的ips从字符串转换为整数:

class User < ActiveRecord::Base
  [:current_sign_in_ip, :last_sign_in_ip].each do |field|
    define_method(field) do
      ip = read_attribute(field)
      return nil unless ip
      ip += 4_294_967_296 if ip < 0 # Convert from 2's complement
      "#{(ip & 0xFF000000) >> 24}.#{(ip & 0x00FF0000) >> 16}.#{(ip & 0x0000FF00) >> 8}.#{ip & 0x000000FF}"
    end

    define_method("#{field}=") do |value|
      quads = value.split('.')
      if quads.length == 4
        as_int = (quads[0].to_i * (2**24)) + (quads[1].to_i * (2**16)) + (quads[2].to_i * (2**8)) + quads[3].to_i
        as_int -= 4_294_967_296 if as_int > 2147483647 # Convert to 2's complement
      else
        as_int = nil
      end
      write_attribute(field, as_int)
    end

  end
end

此代码工作正常,它将字符串转换为整数并保存它们。但是,我希望此代码仅运行before_create操作。我试图把它放在before_create do块中,但我收到undefined method define_method' for #<User:0x007fb97c7076b8>的错误。即使你可以指引我走向正确的方向,那也很棒。

由于

1 个答案:

答案 0 :(得分:2)

你必须针对对象的本征类执行它:

before_create do
  class << self
    [:current_sign_in_ip, :last_sign_in_ip].each do |field|
      define_method(field) do
        ip = read_attribute(field)
        return nil unless ip
        ip += 4_294_967_296 if ip < 0 # Convert from 2's complement
        "#{(ip & 0xFF000000) >> 24}.#{(ip & 0x00FF0000) >> 16}.#{(ip & 0x0000FF00) >> 8}.#{ip & 0x000000FF}"
      end

      define_method("#{field}=") do |value|
        quads = value.split('.')
        if quads.length == 4
          as_int = (quads[0].to_i * (2**24)) + (quads[1].to_i * (2**16)) + (quads[2].to_i * (2**8)) + quads[3].to_i
          as_int -= 4_294_967_296 if as_int > 2147483647 # Convert to 2's complement
        else
          as_int = nil
        end
        write_attribute(field, as_int)
      end

    end
  end
end