module Sparrow::ClassMethods

基础通用非数据表对应类型的类方法设定。

Constants

DEFAULT_PRIMARY_KEY_NAME

默认的主键名称

Attributes

primary_key[R]

@!attribute [r] primary_key

当前实体类的主键属性名。
@return [Symbol] 主键属性名称。

Public Instance Methods

attribute_keys() click to toggle source

当前实体类所有的字段名。为一个数组,每个元素为一个符号,代表一个属性的名称。 属性包含了在当前实体类定义的属性以及继承自父类的属性。如果是多层继承,会依次获取各级父类的属性。

@return [Array<Symbol>] 返回实体类所有字段属性名。

# File lib/sparrow/class_methods.rb, line 22
def attribute_keys
  # 获取本体的属性,如果为 nil 则赋值为空数组
  attr_keys_val = instance_variable_get('@attribute_keys')
  attr_keys_val = instance_variable_set('@attribute_keys', []) if attr_keys_val.nil?
  # 获取继承类的属性,直到本类为止
  acs = ancestors.dup
  acs.shift
  attr_keys_val = [acs.first.attribute_keys, attr_keys_val].flatten.uniq if acs.include?(::Sparrow::Base) && acs.first != ::Sparrow::Base
  # 返回最终结果
  attr_keys_val
end
define_object_attribute(attr_name, attr_class, **options) click to toggle source

为当前类定义一个属性,这个属性包括获取方法和设置方法,并且根据定义的属性类型会在设置时自动转化为对应的数据。

@param [Symbol, String] attr_name 属性名称。 @param [Class] attr_class 属性的类型。可以是 Integer 整形数;Float 浮点型数;

<b>Time DateTime Date</b> 三种时间日期类型,或者其他类型。

@param [Hash] options 额外的可选设置。 @option options [Boolean] :primary_key 作为主键属性的名称。默认为 true 的字段。 @option options [Object] :default 默认值。如果设定了该可选项,且获取到的结果为空时,则一定返回默认值。

因此设定后之后故意赋值为 nil 则不起作用,除非默认值也是 nil 或者不设定默认值。
# File lib/sparrow/class_methods.rb, line 45
def define_object_attribute(attr_name, attr_class, **options)
  # 设置获取方法名称和设置方法名称
  getter_name = attr_name.to_s
  setter_name = "#{attr_name}="
  instance_var_name = "@#{attr_name}"

  # 设置主键属性,当可选项 primary_key 被设置为 true 或者当前还没有主键且当前属性名为 'id' 时会被设置为主键
  @primary_key = getter_name if options[:primary_key] || (primary_key.blank? && getter_name == DEFAULT_PRIMARY_KEY_NAME)

  # 定义读取方法
  define_method(getter_name) do
    val = instance_variable_get(instance_var_name)
    # 当设定了默认值且获取到的值为 nil 时使用默认值。
    # 调试时输出用 "class: #{self}, getter_name: #{getter_name}, options: #{options}"
    val = options[:default] if options.key?(:default) && val.nil?
    val
  end

  # 根据类别定义赋值方法
  if attr_class == ::Integer
    # 如果是整形数,设置时进行转化
    define_method(setter_name) do |value|
      instance_variable_set(instance_var_name, value.to_i)
    end
  elsif attr_class == ::Float
    # 如果是浮点数,设置时进行转化
    define_method(setter_name) do |value|
      instance_variable_set(instance_var_name, value.to_f)
    end
  elsif [::Date, ::DateTime, ::Time].include?(attr_class)
    # 如果是时间或者日期类型,设置时进行转化
    define_method(setter_name) do |value|
      val = nil
      case value
      when ::Date, ::DateTime, ::Time
        val = value
      when ::String
        val = attr_class.parse(value)
        val = val.localtime if attr_class.is_a?(::Time)
        val = val.localtime.to_datetime if attr_class.is_a?(::DateTime)
      end
      instance_variable_set(instance_var_name, val)
    end
  elsif [::Hash, ::Array].include?(attr_class)
    # 如果是散列或者数组的时候,要分别处理
    define_method(setter_name) do |value|
      val = case value
            when attr_class
              value
            when ::String
              # begin
              ::JSON.parse(value)
              # rescue ::StandardError
              #   attr_class.new
              # end
            end
      instance_variable_set(instance_var_name, val)
    end
  elsif attr_class == ::Sparrow::Boolean
    # 如果是布尔值类型
    define_method(setter_name) do |value|
      instance_variable_set(instance_var_name, value.present?)
    end
  else
    # 其他类型原封不动
    define_method(setter_name) do |value|
      instance_variable_set(instance_var_name, value)
    end
  end

  # 将定义好的属性记录当当前属性列表中
  if @attribute_keys.blank?
    @attribute_keys = [attr_name]
  else
    @attribute_keys << attr_name
  end
end
Also aliased as: field
define_object_attributes(attrs_class, *args, **options) click to toggle source

定义多个同类型的属性。每一个单体定义都可参考 {#define_object_attribute} 方法。

@param [Class] attrs_class 属性的类型。 @param [Array] args 多个属性的名称数组。 @param [Hash] options 额外的可选设置。

# File lib/sparrow/class_methods.rb, line 131
def define_object_attributes(attrs_class, *args, **options)
  # puts "args, type and options: args => #{args.inspect}, type => #{attrs_class.inspect}, options => #{options.inspect}"
  args.each { |attr_name| define_object_attribute(attr_name, attrs_class, **options) }
end
Also aliased as: fields
field(attr_name, attr_class, **options)
fields(attrs_class, *args, **options)
i18n(name, type: :label, scope: nil, options: {}) click to toggle source

快速获取 I18n 文本的方法。会根据当前类自动选择路径查找。

@param [Symbol, String] name 对应 I18n 文件中的最终名称。 @param [Symbol, String] type 可选的。对应 I18n 文件中该名称所属的上一级命名空间,默认为 :label 值。 @param [String, Symbol] scope 可选的。对应 I18n 文件中上一级命名空间之前,sparrow 命名空间之下的所有命名空间。

每个命名空间之间用半角符号 +.+ 隔开。没有给出则默认使用当前类以及类的命名空间作为路径。

@param [Hash] options 可选的。其他参数。主要用来设定模板文字中的变量使用。

@return [String] 返回对应的字符串。

# File lib/sparrow/class_methods.rb, line 148
def i18n(name, type: :label, scope: nil, options: {})
  path = scope || to_s.underscore.split('/').compact_blank.join('.')
  current_key = "sparrow.#{path}.#{type}.#{name}"
  default_key = "sparrow.base.#{type}.#{name}"
  ::I18n.exists?(current_key) ? ::I18n.t!(current_key, options) : ::I18n.t!(default_key, options)
end