module Sparrow::ClassMethods
基础通用非数据表对应类型的类方法设定。
Constants
- DEFAULT_PRIMARY_KEY_NAME
默认的主键名称
Attributes
@!attribute [r] primary_key
当前实体类的主键属性名。 @return [Symbol] 主键属性名称。
Public Instance Methods
当前实体类所有的字段名。为一个数组,每个元素为一个符号,代表一个属性的名称。 属性包含了在当前实体类定义的属性以及继承自父类的属性。如果是多层继承,会依次获取各级父类的属性。
@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
为当前类定义一个属性,这个属性包括获取方法和设置方法,并且根据定义的属性类型会在设置时自动转化为对应的数据。
@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
定义多个同类型的属性。每一个单体定义都可参考 {#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
快速获取 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