sparrow-entity 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 76e688bd5ae2f8719fc59ffff9a0bfd183066fd824749d6844ee82b1a8ae841d
4
+ data.tar.gz: a3ed6511da567a4ebdf639e88c324a4827d8583c524c93e6c48ca4c944dff3fb
5
+ SHA512:
6
+ metadata.gz: 694719ed28c757b29df505ebc55b836561ae24aa6df84d51c6956e30dd99b8f84bc1eb79edd63af64c3c2fe6b2d25c4875386214f9c81e2c98584eafe1ecd354
7
+ data.tar.gz: dd6f355238fe4a7b120dc35007a5cdf5cd27d22f5803d4b1c2a8f87984f82f896645489f82a94ccbbfc5e9cb937a9e62fcfc090fc23ab51b7097c6d51a86e099
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /log/
7
+ /pkg/
8
+ /spec/examples.txt
9
+ /spec/reports/
10
+ /tmp/
11
+ **/.DS_Store
12
+ /documents/outputs/
13
+ /.vscode/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,77 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'bin/**/*'
4
+ - 'examples/**/*'
5
+ NewCops: enable
6
+ SuggestExtensions: false
7
+
8
+ # 弱ruby版本的gem,所有目前不需要检测ruby版本
9
+ Gemspec/RequiredRubyVersion:
10
+ Enabled: false
11
+
12
+ Layout/EndOfLine:
13
+ Enabled: false
14
+ Layout/LineLength:
15
+ Max: 400
16
+
17
+ Lint/RaiseException:
18
+ Enabled: true
19
+ Lint/StructNewOverride:
20
+ Enabled: true
21
+
22
+ Metrics/AbcSize:
23
+ Enabled: true
24
+ Max: 200
25
+ # 块的最大长度,因为API文件中会通过块包含通用路由,所以这里放大一些。
26
+ Metrics/BlockLength:
27
+ Max: 100
28
+ Exclude:
29
+ - 'spec/**/*_spec.rb'
30
+ Metrics/BlockNesting:
31
+ Max: 5
32
+ Metrics/ClassLength:
33
+ Max: 600
34
+ Metrics/MethodLength:
35
+ Enabled: true
36
+ Max: 100
37
+ # 保持和 Class 的长度一致。对于一些纯设定类仅300行并不够,600行以上需要拆分。
38
+ Metrics/ModuleLength:
39
+ Max: 600
40
+ Metrics/PerceivedComplexity:
41
+ Max: 50
42
+ Metrics/CyclomaticComplexity:
43
+ Max: 50
44
+
45
+ Naming/PredicateName:
46
+ Exclude:
47
+ - 'spec/**/*'
48
+
49
+ Style/AsciiComments:
50
+ Enabled: false
51
+ Style/Encoding:
52
+ Enabled: false
53
+ Style/FormatString:
54
+ Enabled: false
55
+ Style/FormatStringToken:
56
+ Enabled: false
57
+ Style/HashEachMethods:
58
+ Enabled: false
59
+ Style/HashTransformKeys:
60
+ Enabled: false
61
+ Style/HashTransformValues:
62
+ Enabled: false
63
+ Style/Next:
64
+ MinBodyLength: 4
65
+ Style/IfInsideElse:
66
+ Enabled: false
67
+ Style/NumericLiterals:
68
+ Enabled: false
69
+ Style/RaiseArgs:
70
+ Enabled: false
71
+ Style/RescueModifier:
72
+ Enabled: false
73
+ Style/TrailingCommaInHashLiteral:
74
+ Enabled: true
75
+ EnforcedStyleForMultiline: consistent_comma
76
+ Style/TrailingCommaInArrayLiteral:
77
+ EnforcedStyleForMultiline: consistent_comma
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ sparrow
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.6.8
data/CHANGELOG ADDED
File without changes
data/CODE_OF_CONDUCT ADDED
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at shiner527@hotmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in sparrow.gemspec
8
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,94 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sparrow-entity (0.1.0)
5
+ activemodel
6
+ activemodel_object_info (~> 0.2.0)
7
+ activesupport
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (6.1.4.4)
13
+ activesupport (= 6.1.4.4)
14
+ activemodel_object_info (0.2.0)
15
+ activesupport
16
+ activesupport (6.1.4.4)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (>= 1.6, < 2)
19
+ minitest (>= 5.1)
20
+ tzinfo (~> 2.0)
21
+ zeitwerk (~> 2.3)
22
+ ast (2.4.2)
23
+ coderay (1.1.3)
24
+ concurrent-ruby (1.1.9)
25
+ diff-lcs (1.5.0)
26
+ docile (1.4.0)
27
+ i18n (1.8.11)
28
+ concurrent-ruby (~> 1.0)
29
+ method_source (1.0.0)
30
+ minitest (5.15.0)
31
+ parallel (1.21.0)
32
+ parser (3.0.3.2)
33
+ ast (~> 2.4.1)
34
+ pry (0.14.1)
35
+ coderay (~> 1.1)
36
+ method_source (~> 1.0)
37
+ rainbow (3.0.0)
38
+ rake (13.0.6)
39
+ regexp_parser (2.2.0)
40
+ rexml (3.2.5)
41
+ rspec (3.10.0)
42
+ rspec-core (~> 3.10.0)
43
+ rspec-expectations (~> 3.10.0)
44
+ rspec-mocks (~> 3.10.0)
45
+ rspec-core (3.10.1)
46
+ rspec-support (~> 3.10.0)
47
+ rspec-expectations (3.10.1)
48
+ diff-lcs (>= 1.2.0, < 2.0)
49
+ rspec-support (~> 3.10.0)
50
+ rspec-mocks (3.10.2)
51
+ diff-lcs (>= 1.2.0, < 2.0)
52
+ rspec-support (~> 3.10.0)
53
+ rspec-support (3.10.3)
54
+ rubocop (1.24.0)
55
+ parallel (~> 1.10)
56
+ parser (>= 3.0.0.0)
57
+ rainbow (>= 2.2.2, < 4.0)
58
+ regexp_parser (>= 1.8, < 3.0)
59
+ rexml
60
+ rubocop-ast (>= 1.15.0, < 2.0)
61
+ ruby-progressbar (~> 1.7)
62
+ unicode-display_width (>= 1.4.0, < 3.0)
63
+ rubocop-ast (1.15.1)
64
+ parser (>= 3.0.1.1)
65
+ ruby-progressbar (1.11.0)
66
+ simplecov (0.21.2)
67
+ docile (~> 1.1)
68
+ simplecov-html (~> 0.11)
69
+ simplecov_json_formatter (~> 0.1)
70
+ simplecov-html (0.12.3)
71
+ simplecov_json_formatter (0.1.3)
72
+ tzinfo (2.0.4)
73
+ concurrent-ruby (~> 1.0)
74
+ unicode-display_width (2.1.0)
75
+ webrick (1.7.0)
76
+ yard (0.9.27)
77
+ webrick (~> 1.7.0)
78
+ zeitwerk (2.5.3)
79
+
80
+ PLATFORMS
81
+ ruby
82
+
83
+ DEPENDENCIES
84
+ bundler
85
+ pry
86
+ rake
87
+ rspec
88
+ rubocop
89
+ simplecov
90
+ sparrow-entity!
91
+ yard
92
+
93
+ BUNDLED WITH
94
+ 1.17.3
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Shiner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README ADDED
@@ -0,0 +1,43 @@
1
+ # Sparrow
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sparrow`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'sparrow'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install sparrow
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/sparrow. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
40
+
41
+ ## Code of Conduct
42
+
43
+ Everyone interacting in the Sparrow project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/sparrow/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ task default: :spec
8
+
9
+ task :console do
10
+ ruby 'bin/console'
11
+ end
12
+ task c: :console
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'sparrow'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require 'pry'
11
+ Pry.start
12
+
13
+ #require "irb"
14
+ #IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ en:
2
+ sparrow:
3
+ base:
4
+ label:
5
+ invalid_label: invalid label
@@ -0,0 +1,5 @@
1
+ zh-CN:
2
+ sparrow:
3
+ base:
4
+ label:
5
+ invalid_label: 无效的内容
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sparrow
4
+ #
5
+ # 对麻雀实体类进行基础类定义和设置通用的属性方法等。所有实际使用的实体类都要基于此类进行设置。
6
+ #
7
+ # @author Shiner <shiner527@hotmail.com>
8
+ #
9
+ class Base
10
+ extend ::ActiveModel::Callbacks
11
+ extend ::ActiveModel::Translation
12
+ include ::ActiveModel::Dirty
13
+ include ::ActivemodelObjectInfo::Base
14
+
15
+ extend ClassMethods
16
+ # @!parse extend ClassMethods
17
+
18
+ # 定义初始化方法的回调支持
19
+ define_model_callbacks :initialize
20
+
21
+ #
22
+ # 初始化基本实体类。
23
+ #
24
+ # @param [Hash] attribute_settings 一个包含字段名称和对应值的散列。
25
+ #
26
+ def initialize(**attribute_settings)
27
+ run_callbacks(:initialize) do
28
+ attribute_settings.each do |key, value|
29
+ # puts "key=#{key}, value=#{value}, respond=#{respond_to?(key.to_s + '=')}"
30
+ __send__("#{key}=", value) if respond_to?("#{key}=")
31
+ end
32
+ true # 这里必须保证为true让block值为真,确保回调会被调用
33
+ end
34
+ end
35
+
36
+ #
37
+ # 获取当前实例中通过类设定属性的键值对,键名为属性名,值为对应属性的值。
38
+ #
39
+ # @return [Hash] 返回对应的属性名和属性值的键值对。
40
+ #
41
+ def attributes
42
+ attribute_names.index_with { |attribute_name| __send__(attribute_name) }
43
+ end
44
+
45
+ #
46
+ # 获取当前实例中通过类方法 {Sparrow::ClassMethods#define_object_attribute} 设定的属性。
47
+ #
48
+ # @return [Array<Symbol>] 返回一个数组,每个元素均为当前实例对应的类中设定的属性名。
49
+ #
50
+ def attribute_names
51
+ self.class.attribute_keys.compact_blank.map(&:to_sym)
52
+ end
53
+
54
+ #
55
+ # 提供实例中快速获取 I18n 文本的方法。会根据当前类自动选择路径查找。详情参照对应同名类方法。
56
+ #
57
+ # @param [Symbol, String] name 对应 I18n 文件中的最终名称。
58
+ # @param [Symbol, String] type 可选的。对应 I18n 文件中该名称所属的上一级命名空间,默认为 +:label+ 值。
59
+ # @param [String, Symbol] scope 可选的。对应 I18n 文件中上一级命名空间之前,sparrow 命名空间之下的所有命名空间。
60
+ # 每个命名空间之间用半角符号 +.+ 隔开。没有给出则默认使用当前类以及类的命名空间作为路径。
61
+ # @param [Hash] options 可选的。其他参数。主要用来设定模板文字中的变量使用。
62
+ #
63
+ # @return [String] 返回对应的字符串。
64
+ #
65
+ def i18n(name, type: :label, scope: nil, options: {})
66
+ self.class.i18n(name, type: type, scope: scope, options: options)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sparrow
4
+ #
5
+ # 基础通用非数据表对应类型的类方法设定。
6
+ #
7
+ module ClassMethods
8
+ # 默认的主键名称
9
+ DEFAULT_PRIMARY_KEY_NAME = 'id'
10
+
11
+ # @!attribute [r] primary_key
12
+ # 当前实体类的主键属性名。
13
+ # @return [Symbol] 主键属性名称。
14
+ attr_reader :primary_key
15
+
16
+ #
17
+ # 当前实体类所有的字段名。为一个数组,每个元素为一个符号,代表一个属性的名称。
18
+ # 属性包含了在当前实体类定义的属性以及继承自父类的属性。如果是多层继承,会依次获取各级父类的属性。
19
+ #
20
+ # @return [Array<Symbol>] 返回实体类所有字段属性名。
21
+ #
22
+ def attribute_keys
23
+ # 获取本体的属性,如果为 nil 则赋值为空数组
24
+ attr_keys_val = instance_variable_get('@attribute_keys')
25
+ attr_keys_val = instance_variable_set('@attribute_keys', []) if attr_keys_val.nil?
26
+ # 获取继承类的属性,直到本类为止
27
+ acs = ancestors.dup
28
+ acs.shift
29
+ attr_keys_val = [acs.first.attribute_keys, attr_keys_val].flatten.uniq if acs.include?(::Sparrow::Base) && acs.first != ::Sparrow::Base
30
+ # 返回最终结果
31
+ attr_keys_val
32
+ end
33
+
34
+ #
35
+ # 为当前类定义一个属性,这个属性包括获取方法和设置方法,并且根据定义的属性类型会在设置时自动转化为对应的数据。
36
+ #
37
+ # @param [Symbol, String] attr_name 属性名称。
38
+ # @param [Class] attr_class 属性的类型。可以是 *Integer* 整形数;<b>Float</b> 浮点型数;
39
+ # <b>Time DateTime Date</b> 三种时间日期类型,或者其他类型。
40
+ # @param [Hash] options 额外的可选设置。
41
+ # @option options [Boolean] :primary_key 作为主键属性的名称。默认为 +true+ 的字段。
42
+ # @option options [Object] :default 默认值。如果设定了该可选项,且获取到的结果为空时,则一定返回默认值。
43
+ # 因此设定后之后故意赋值为 nil 则不起作用,除非默认值也是 nil 或者不设定默认值。
44
+ #
45
+ def define_object_attribute(attr_name, attr_class, **options)
46
+ # 设置获取方法名称和设置方法名称
47
+ getter_name = attr_name.to_s
48
+ setter_name = "#{attr_name}="
49
+ instance_var_name = "@#{attr_name}"
50
+
51
+ # 设置主键属性,当可选项 primary_key 被设置为 true 或者当前还没有主键且当前属性名为 'id' 时会被设置为主键
52
+ @primary_key = getter_name if options[:primary_key] || (primary_key.blank? && getter_name == DEFAULT_PRIMARY_KEY_NAME)
53
+
54
+ # 定义读取方法
55
+ define_method(getter_name) do
56
+ val = instance_variable_get(instance_var_name)
57
+ # 当设定了默认值且获取到的值为 nil 时使用默认值。
58
+ # 调试时输出用 "class: #{self}, getter_name: #{getter_name}, options: #{options}"
59
+ val = options[:default] if options.key?(:default) && val.nil?
60
+ val
61
+ end
62
+
63
+ # 根据类别定义赋值方法
64
+ if attr_class == ::Integer
65
+ # 如果是整形数,设置时进行转化
66
+ define_method(setter_name) do |value|
67
+ instance_variable_set(instance_var_name, value.to_i)
68
+ end
69
+ elsif attr_class == ::Float
70
+ # 如果是浮点数,设置时进行转化
71
+ define_method(setter_name) do |value|
72
+ instance_variable_set(instance_var_name, value.to_f)
73
+ end
74
+ elsif [::Date, ::DateTime, ::Time].include?(attr_class)
75
+ # 如果是时间或者日期类型,设置时进行转化
76
+ define_method(setter_name) do |value|
77
+ val = nil
78
+ case value
79
+ when ::Date, ::DateTime, ::Time
80
+ val = value
81
+ when ::String
82
+ val = attr_class.parse(value)
83
+ end
84
+ instance_variable_set(instance_var_name, val)
85
+ end
86
+ elsif [::Hash, ::Array].include?(attr_class)
87
+ # 如果是散列或者数组的时候,要分别处理
88
+ define_method(setter_name) do |value|
89
+ val = case value
90
+ when attr_class
91
+ value
92
+ when ::String
93
+ # begin
94
+ ::JSON.parse(value)
95
+ # rescue ::StandardError
96
+ # attr_class.new
97
+ # end
98
+ end
99
+ instance_variable_set(instance_var_name, val)
100
+ end
101
+ else
102
+ # 其他类型原封不动
103
+ define_method(setter_name) do |value|
104
+ instance_variable_set(instance_var_name, value)
105
+ end
106
+ end
107
+
108
+ # 将定义好的属性记录当当前属性列表中
109
+ if @attribute_keys.blank?
110
+ @attribute_keys = [attr_name]
111
+ else
112
+ @attribute_keys << attr_name
113
+ end
114
+ end
115
+ alias field define_object_attribute
116
+
117
+ #
118
+ # 定义多个同类型的属性。每一个单体定义都可参考 {#define_object_attribute} 方法。
119
+ #
120
+ # @param [Class] attrs_class 属性的类型。
121
+ # @param [Array] args 多个属性的名称数组。
122
+ # @param [Hash] options 额外的可选设置。
123
+ #
124
+ def define_object_attributes(attrs_class, *args, **options)
125
+ # puts "args, type and options: args => #{args.inspect}, type => #{attrs_class.inspect}, options => #{options.inspect}"
126
+ args.each { |attr_name| define_object_attribute(attr_name, attrs_class, **options) }
127
+ end
128
+ alias fields define_object_attributes
129
+
130
+ #
131
+ # 快速获取 I18n 文本的方法。会根据当前类自动选择路径查找。
132
+ #
133
+ # @param [Symbol, String] name 对应 I18n 文件中的最终名称。
134
+ # @param [Symbol, String] type 可选的。对应 I18n 文件中该名称所属的上一级命名空间,默认为 +:label+ 值。
135
+ # @param [String, Symbol] scope 可选的。对应 I18n 文件中上一级命名空间之前,sparrow 命名空间之下的所有命名空间。
136
+ # 每个命名空间之间用半角符号 +.+ 隔开。没有给出则默认使用当前类以及类的命名空间作为路径。
137
+ # @param [Hash] options 可选的。其他参数。主要用来设定模板文字中的变量使用。
138
+ #
139
+ # @return [String] 返回对应的字符串。
140
+ #
141
+ def i18n(name, type: :label, scope: nil, options: {})
142
+ path = scope || to_s.underscore.split('/').compact_blank.join('.')
143
+ current_key = "sparrow.#{path}.#{type}.#{name}"
144
+ default_key = "sparrow.base.#{type}.#{name}"
145
+ ::I18n.exists?(current_key) ? ::I18n.t!(current_key, options) : ::I18n.t!(default_key, options)
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sparrow
4
+ # 当前版本号
5
+ VERSION = '0.1.0'
6
+ # 当前综述
7
+ SUMMARY = 'Provide an easy approach to build entity object for data that can not be reflected to database tables.'
8
+ # 当前详述
9
+ DESCRIPTION = 'Provide an easy approach to build entity object for data that can not be reflected to database tables.'
10
+ end
data/lib/sparrow.rb ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sparrow/version'
4
+ require 'active_support'
5
+ require 'active_model'
6
+ require 'activemodel_object_info'
7
+ require 'sparrow/class_methods'
8
+ require 'sparrow/base'
9
+
10
+ #
11
+ # 实体总模组,统括所有支持基于 **ActiveModel** 的实体类的内容。
12
+ #
13
+ # @author Shiner <shiner527@hotmail.com>
14
+ #
15
+ module Sparrow
16
+ # 加载本插件自带默认的 i18n 信息内容
17
+ ::Dir[::File.expand_path('lib/config/locales/sparrow/*.yml')].each { |f| ::I18n.load_path << f }
18
+ end
data/sparrow.gemspec ADDED
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'sparrow/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'sparrow-entity'
9
+ spec.version = Sparrow::VERSION
10
+ spec.authors = ['shiner']
11
+ spec.email = ['shiner527@hotmail.com']
12
+
13
+ spec.summary = Sparrow::SUMMARY
14
+ spec.description = Sparrow::DESCRIPTION
15
+ spec.homepage = 'https://github.com/shiner527/sparrow'
16
+ spec.license = 'MIT'
17
+
18
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
19
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
20
+ if spec.respond_to?(:metadata)
21
+ # spec.metadata['allowed_push_host'] = "Set to 'http://mygemserver.com'"
22
+
23
+ spec.metadata['homepage_uri'] = spec.homepage
24
+ spec.metadata['source_code_uri'] = 'https://github.com/shiner527/sparrow.git'
25
+ spec.metadata['changelog_uri'] = 'https://github.com/shiner527/sparrow/CHANGELOG'
26
+ spec.metadata['rubygems_mfa_required'] = 'false'
27
+ else
28
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
29
+ 'public gem pushes.'
30
+ end
31
+
32
+ # Specify which files should be added to the gem when it is released.
33
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
34
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
35
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
36
+ end
37
+ spec.bindir = 'bin'
38
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
39
+ spec.require_paths = ['lib']
40
+
41
+ spec.add_dependency 'activemodel'
42
+ spec.add_dependency 'activemodel_object_info', '~> 0.2.0'
43
+ spec.add_dependency 'activesupport'
44
+
45
+ spec.add_development_dependency 'bundler'
46
+ spec.add_development_dependency 'pry'
47
+ spec.add_development_dependency 'rake'
48
+ spec.add_development_dependency 'rspec'
49
+ spec.add_development_dependency 'rubocop'
50
+ spec.add_development_dependency 'simplecov'
51
+ spec.add_development_dependency 'yard'
52
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sparrow-entity
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - shiner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-12-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel_object_info
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: yard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Provide an easy approach to build entity object for data that can not
154
+ be reflected to database tables.
155
+ email:
156
+ - shiner527@hotmail.com
157
+ executables:
158
+ - console
159
+ - setup
160
+ extensions: []
161
+ extra_rdoc_files: []
162
+ files:
163
+ - ".gitignore"
164
+ - ".rspec"
165
+ - ".rubocop.yml"
166
+ - ".ruby-gemset"
167
+ - ".ruby-version"
168
+ - CHANGELOG
169
+ - CODE_OF_CONDUCT
170
+ - Gemfile
171
+ - Gemfile.lock
172
+ - LICENSE
173
+ - README
174
+ - Rakefile
175
+ - bin/console
176
+ - bin/setup
177
+ - lib/config/locales/sparrow/base.en.yml
178
+ - lib/config/locales/sparrow/base.zh-CN.yml
179
+ - lib/sparrow.rb
180
+ - lib/sparrow/base.rb
181
+ - lib/sparrow/class_methods.rb
182
+ - lib/sparrow/version.rb
183
+ - sparrow.gemspec
184
+ homepage: https://github.com/shiner527/sparrow
185
+ licenses:
186
+ - MIT
187
+ metadata:
188
+ homepage_uri: https://github.com/shiner527/sparrow
189
+ source_code_uri: https://github.com/shiner527/sparrow.git
190
+ changelog_uri: https://github.com/shiner527/sparrow/CHANGELOG
191
+ rubygems_mfa_required: 'false'
192
+ post_install_message:
193
+ rdoc_options: []
194
+ require_paths:
195
+ - lib
196
+ required_ruby_version: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ requirements: []
207
+ rubygems_version: 3.0.9
208
+ signing_key:
209
+ specification_version: 4
210
+ summary: Provide an easy approach to build entity object for data that can not be
211
+ reflected to database tables.
212
+ test_files: []