Module: Sparrow::ClassMethods

Included in:
Base
Defined in:
lib/sparrow/class_methods.rb

Overview

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

Constant Summary collapse

DEFAULT_PRIMARY_KEY_NAME =

默认的主键名称

'id'

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#primary_keyObject (readonly)

Returns the value of attribute primary_key.



14
15
16
# File 'lib/sparrow/class_methods.rb', line 14

def primary_key
  @primary_key
end

Instance Method Details

#attribute_keysArray<Symbol>

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

Returns:

  • (Array<Symbol>)

    返回实体类所有字段属性名。



22
23
24
25
26
27
28
29
30
31
32
# 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) ⇒ Object Also known as: field

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

Parameters:

  • attr_name (Symbol, String)

    属性名称。

  • attr_class (Class)

    属性的类型。可以是 Integer 整形数;Float 浮点型数; Time DateTime Date 三种时间日期类型,或者其他类型。

  • options (Hash)

    额外的可选设置。

Options Hash (**options):

  • :primary_key (Boolean)

    作为主键属性的名称。默认为 true 的字段。

  • :default (Object)

    默认值。如果设定了该可选项,且获取到的结果为空时,则一定返回默认值。 因此设定后之后故意赋值为 nil 则不起作用,除非默认值也是 nil 或者不设定默认值。



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 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

#define_object_attributes(attrs_class, *args, **options) ⇒ Object Also known as: fields

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

Parameters:

  • attrs_class (Class)

    属性的类型。

  • args (Array)

    多个属性的名称数组。

  • options (Hash)

    额外的可选设置。



131
132
133
134
# 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

#i18n(name, type: :label, scope: nil, options: {}) ⇒ String

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

Parameters:

  • name (Symbol, String)

    对应 I18n 文件中的最终名称。

  • type (Symbol, String) (defaults to: :label)

    可选的。对应 I18n 文件中该名称所属的上一级命名空间,默认为 :label 值。

  • scope (String, Symbol) (defaults to: nil)

    可选的。对应 I18n 文件中上一级命名空间之前,sparrow 命名空间之下的所有命名空间。 每个命名空间之间用半角符号 . 隔开。没有给出则默认使用当前类以及类的命名空间作为路径。

  • options (Hash) (defaults to: {})

    可选的。其他参数。主要用来设定模板文字中的变量使用。

Returns:

  • (String)

    返回对应的字符串。



148
149
150
151
152
153
# 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