activemodel_object_info 0.3.3 → 0.4.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 +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG +9 -1
- data/Gemfile.lock +1 -1
- data/README.md +147 -17
- data/README.zh-CN.md +171 -0
- data/lib/activemodel_object_info/base.rb +78 -32
- data/lib/activemodel_object_info/deleted_operation.rb +52 -14
- data/lib/activemodel_object_info/table_definition.rb +43 -5
- data/lib/activemodel_object_info/version.rb +1 -1
- data/lib/activemodel_object_info.rb +17 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 80913d0545f39b6b56ea20826e6c5da37c3fbec7645f988c5439f85f6ac2eedc
|
|
4
|
+
data.tar.gz: 8f839ed3448156219e6c4da35c9eb69d9eb7d4dca97ef48f1c89b937ea2a782e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a8c1005c3e1887dd377deb8ab79d1d9bad079dea09ac81e24ff484e59efdb44c3e3c6c7ba4741237954d944f0b5780ff00f9e7530ebe465c603eedc9f0aeb5a1
|
|
7
|
+
data.tar.gz: 5bd16bc43f2c13b58bfa037ee6505777d80a97d455b7744d75f32cd928348a1d2d0e0cc638acc0070662b42792f83972c365ccd00c81860980f05196afc6bd32
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.7.7
|
data/CHANGELOG
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
## [0.4.0] - 2026-07-28
|
|
5
|
+
### Fixed
|
|
6
|
+
- Fixed Ruby 3.x keyword arguments compatibility issue for `instance_info` method, while keeping 100% backward compatibility for existing usages.
|
|
7
|
+
|
|
8
|
+
## [0.3.4] - 2021-04-19
|
|
9
|
+
- First Version
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,43 +1,173 @@
|
|
|
1
1
|
# Activemodel::Object::Info
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[English](README.md) | [中文文档](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Activemodel::Object::Info** is a Ruby Gem designed to extend `ActiveModel` and `ActiveRecord`. It provides an elegant and standardized way to handle common business requirements such as API data formatting, audit trails generation in database migrations, and soft-delete capabilities.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Features](#features)
|
|
10
|
+
- [Applicable Scenarios](#applicable-scenarios)
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Usage](#usage)
|
|
13
|
+
- [1. Data Formatting (Base)](#1-data-formatting-base)
|
|
14
|
+
- [2. Migration Macros (TableDefinition)](#2-migration-macros-tabledefinition)
|
|
15
|
+
- [3. Soft Delete (DeletedOperation)](#3-soft-delete-deletedoperation)
|
|
16
|
+
- [Development & Testing](#development--testing)
|
|
17
|
+
- [License](#license)
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
1. **Model Data Formatting (`Base`)**: Safely and flexibly format `ActiveRecord` instances into Hashes (JSON ready) with whitelisting, blacklisting, aliasing, and custom formatting.
|
|
22
|
+
2. **Database Migration Macros (`TableDefinition`)**: One-click generation of audit fields (e.g., `created_by`, `updated_by`, `deleted_by`) and their corresponding timestamps.
|
|
23
|
+
3. **Soft Delete (`DeletedOperation`)**: Standardized soft-delete implementation using an integer flag, coupled with automatic `default_scope` injection and audit trail recording.
|
|
24
|
+
|
|
25
|
+
## Applicable Scenarios
|
|
26
|
+
|
|
27
|
+
- **RESTful API Development**: When you need a unified and configurable way to serialize ActiveRecord models into JSON responses, avoiding sensitive data leakage.
|
|
28
|
+
- **Enterprise / B2B Systems**: When strict data audit trails are required (tracking exactly *who* performed the creation, update, or deletion and *when*).
|
|
29
|
+
- **Data Retention Requirements**: Systems that prohibit hard deletion (destroy) and require records to be marked as deleted (Soft Delete) instead.
|
|
6
30
|
|
|
7
31
|
## Installation
|
|
8
32
|
|
|
9
33
|
Add this line to your application's Gemfile:
|
|
10
34
|
|
|
11
35
|
```ruby
|
|
12
|
-
gem 'activemodel-object-info'
|
|
36
|
+
gem 'activemodel-object-info', '~> 0.4.0'
|
|
13
37
|
```
|
|
14
38
|
|
|
15
39
|
And then execute:
|
|
16
40
|
|
|
17
|
-
|
|
41
|
+
```bash
|
|
42
|
+
$ bundle install
|
|
43
|
+
```
|
|
18
44
|
|
|
19
|
-
|
|
45
|
+
## Usage
|
|
20
46
|
|
|
21
|
-
|
|
47
|
+
### 1. Data Formatting (Base)
|
|
22
48
|
|
|
23
|
-
|
|
49
|
+
The `ActivemodelObjectInfo::Base` module adds the `instance_info` method to your models. It allows you to output formatted hashes based on predefined or runtime configurations.
|
|
24
50
|
|
|
25
|
-
|
|
51
|
+
**Setup in Model:**
|
|
26
52
|
|
|
27
|
-
|
|
53
|
+
```ruby
|
|
54
|
+
class User < ApplicationRecord
|
|
55
|
+
include ActivemodelObjectInfo::Base
|
|
56
|
+
|
|
57
|
+
# Define default output configuration
|
|
58
|
+
INSTANCE_INFO = {
|
|
59
|
+
only: [:id, :name, :status, :created_at],
|
|
60
|
+
attributes: [
|
|
61
|
+
:id,
|
|
62
|
+
{ name: :name, as: :user_name }, # Aliasing
|
|
63
|
+
{ name: :status, filter: ->(v) { v == 1 ? 'Active' : 'Inactive' } }, # Custom lambda filter
|
|
64
|
+
{ name: :created_at, format: :date }, # Date formatting ('%Y-%m-%d')
|
|
65
|
+
{ name: :virtual_field, type: :abstract, filter: ->(*) { "#{id}-#{name}" } } # Virtual field
|
|
66
|
+
]
|
|
67
|
+
}.freeze
|
|
68
|
+
end
|
|
69
|
+
```
|
|
28
70
|
|
|
29
|
-
|
|
71
|
+
**Usage:**
|
|
30
72
|
|
|
31
|
-
|
|
73
|
+
```ruby
|
|
74
|
+
user = User.first
|
|
32
75
|
|
|
33
|
-
|
|
76
|
+
# Use the default INSTANCE_INFO constant
|
|
77
|
+
user.instance_info
|
|
78
|
+
# => { id: 1, user_name: "John", status: "Active", created_at: "2026-07-28", virtual_field: "1-John" }
|
|
34
79
|
|
|
35
|
-
|
|
80
|
+
# Override at runtime (Supports Ruby 2.x Hash and Ruby 3.x Keyword Arguments)
|
|
81
|
+
user.instance_info(only: [:id, :name])
|
|
82
|
+
# => { id: 1, name: "John" }
|
|
83
|
+
```
|
|
36
84
|
|
|
37
|
-
|
|
85
|
+
### 2. Migration Macros (TableDefinition)
|
|
38
86
|
|
|
39
|
-
The
|
|
87
|
+
The `ActivemodelObjectInfo::TableDefinition` module extends ActiveRecord's migration capabilities to generate audit fields effortlessly.
|
|
88
|
+
|
|
89
|
+
**Setup:**
|
|
90
|
+
This is usually loaded automatically, but you can explicitly extend it if needed in your initializers.
|
|
91
|
+
|
|
92
|
+
**Usage in Migrations:**
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
class CreateUsers < ActiveRecord::Migration[6.1]
|
|
96
|
+
def change
|
|
97
|
+
create_table :users do |t|
|
|
98
|
+
t.string :name
|
|
99
|
+
|
|
100
|
+
# Generates full audit suite:
|
|
101
|
+
# created_by, created_at, updated_by, updated_at, deleted(int), deleted_by, deleted_at
|
|
102
|
+
t.generate_operations
|
|
103
|
+
|
|
104
|
+
# Or generate specific custom audit fields:
|
|
105
|
+
# Generates: audit_by (bigint), audit_at (datetime)
|
|
106
|
+
t.operation_columns(:audit)
|
|
107
|
+
|
|
108
|
+
# Generates: my_review_user (bigint), my_review_time (datetime)
|
|
109
|
+
t.operation_columns(:review, operator_prefix: 'my_', operator_suffix: '_user', timestamp_suffix: '_time')
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 3. Soft Delete (DeletedOperation)
|
|
116
|
+
|
|
117
|
+
The `ActivemodelObjectInfo::DeletedOperation` module provides an out-of-the-box soft deletion feature that works perfectly with the fields generated by `TableDefinition`.
|
|
118
|
+
|
|
119
|
+
**Setup in Model:**
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
class User < ApplicationRecord
|
|
123
|
+
include ActivemodelObjectInfo::DeletedOperation
|
|
124
|
+
|
|
125
|
+
# Optional: Override default column names and values if your database uses different conventions
|
|
126
|
+
# DELETED_FIELD = 'is_deleted'
|
|
127
|
+
# DELETED_VALID_VALUE = false
|
|
128
|
+
# DELETED_INVALID_VALUE = true
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Usage:**
|
|
40
133
|
|
|
41
|
-
|
|
134
|
+
```ruby
|
|
135
|
+
# 1. Automatic Scope:
|
|
136
|
+
# The module automatically injects a `default_scope` to hide deleted records.
|
|
137
|
+
User.all # => SELECT * FROM users WHERE deleted = 0
|
|
138
|
+
|
|
139
|
+
# 2. Perform Soft Delete:
|
|
140
|
+
user = User.find(1)
|
|
141
|
+
|
|
142
|
+
# You MUST provide the `user_id` of the operator performing the deletion
|
|
143
|
+
user.soft_delete(user_id: current_user.id)
|
|
144
|
+
# This will:
|
|
145
|
+
# - Set `deleted` to 1
|
|
146
|
+
# - Set `deleted_by` to current_user.id
|
|
147
|
+
# - Set `deleted_at` to Time.now
|
|
148
|
+
# - Call `save`
|
|
149
|
+
|
|
150
|
+
# 3. Soft Delete and refresh updated_at:
|
|
151
|
+
user.soft_delete(user_id: current_user.id, refresh_updated: true)
|
|
152
|
+
|
|
153
|
+
# 4. Strict Soft Delete (raises exception on failure):
|
|
154
|
+
user.soft_delete!(user_id: current_user.id)
|
|
155
|
+
```
|
|
42
156
|
|
|
43
|
-
|
|
157
|
+
## Development & Testing
|
|
158
|
+
|
|
159
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
|
160
|
+
|
|
161
|
+
To run tests:
|
|
162
|
+
```bash
|
|
163
|
+
$ bundle exec rspec
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
To run code style checks:
|
|
167
|
+
```bash
|
|
168
|
+
$ bundle exec rubocop
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/README.zh-CN.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Activemodel::Object::Info
|
|
2
|
+
|
|
3
|
+
[English](README.md) | [中文文档](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
**Activemodel::Object::Info** 是一个用于扩展 `ActiveModel` 和 `ActiveRecord` 的 Ruby Gem。它为日常业务开发中常见的数据输出格式化、数据库迁移中的审计追踪字段生成、以及软删除(Soft Delete)功能提供了优雅且标准化的解决方案。
|
|
6
|
+
|
|
7
|
+
## 目录
|
|
8
|
+
|
|
9
|
+
- [核心特性](#核心特性)
|
|
10
|
+
- [适用场景](#适用场景)
|
|
11
|
+
- [安装指南](#安装指南)
|
|
12
|
+
- [详细使用方法](#详细使用方法)
|
|
13
|
+
- [1. 模型数据格式化输出 (Base)](#1-模型数据格式化输出-base)
|
|
14
|
+
- [2. 数据库迁移宏 (TableDefinition)](#2-数据库迁移宏-tabledefinition)
|
|
15
|
+
- [3. 软删除机制 (DeletedOperation)](#3-软删除机制-deletedoperation)
|
|
16
|
+
- [开发与测试](#开发与测试)
|
|
17
|
+
- [开源协议](#开源协议)
|
|
18
|
+
|
|
19
|
+
## 核心特性
|
|
20
|
+
|
|
21
|
+
1. **模型数据格式化 (`Base`)**:安全、灵活地将 `ActiveRecord` 实例转换为 Hash(便于输出为 JSON)。支持字段白名单、黑名单、字段别名、自定义转换逻辑以及时间格式化。
|
|
22
|
+
2. **数据库迁移宏 (`TableDefinition`)**:在创建数据库表时,一键生成常见的审计字段(例如 `created_by`, `updated_by`, `deleted_by`)以及配套的时间戳。
|
|
23
|
+
3. **软删除机制 (`DeletedOperation`)**:基于整型标记字段的标准软删除实现,自动注入隐藏已删除数据的 `default_scope`,并在删除时强制记录操作人及时间。
|
|
24
|
+
|
|
25
|
+
## 适用场景
|
|
26
|
+
|
|
27
|
+
- **RESTful API 开发**:当你需要统一且高度可配置的方式,将 ActiveRecord 模型序列化为 JSON 响应并过滤掉敏感数据时。
|
|
28
|
+
- **企业级 / B2B 系统后台**:业务上对数据的审计追踪(Audit Trails)要求极其严格,必须精准记录每一条数据是谁在什么时候创建、修改和删除的。
|
|
29
|
+
- **数据留存要求高的系统**:严禁在数据库中执行硬删除(Destroy),要求所有的删除操作均采用软删除(Soft Delete)以备后续追溯。
|
|
30
|
+
|
|
31
|
+
## 安装指南
|
|
32
|
+
|
|
33
|
+
将以下代码添加到你项目中的 Gemfile 里:
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
gem 'activemodel-object-info', '~> 0.4.0'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
然后执行依赖安装:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
$ bundle install
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 详细使用方法
|
|
46
|
+
|
|
47
|
+
### 1. 模型数据格式化输出 (Base)
|
|
48
|
+
|
|
49
|
+
`ActivemodelObjectInfo::Base` 模块为你的模型注入了 `instance_info` 方法。它能让你基于类中预定义的常量或运行时传入的参数,将实例对象输出为格式化的 Hash。
|
|
50
|
+
|
|
51
|
+
**在模型中配置:**
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
class User < ApplicationRecord
|
|
55
|
+
include ActivemodelObjectInfo::Base
|
|
56
|
+
|
|
57
|
+
# 定义默认的输出配置选项
|
|
58
|
+
INSTANCE_INFO = {
|
|
59
|
+
only: [:id, :name, :status, :created_at],
|
|
60
|
+
attributes: [
|
|
61
|
+
:id,
|
|
62
|
+
{ name: :name, as: :user_name }, # 使用 as 设定别名
|
|
63
|
+
{ name: :status, filter: ->(v) { v == 1 ? '活跃' : '停用' } }, # 使用 lambda 自定义转换逻辑
|
|
64
|
+
{ name: :created_at, format: :date }, # 格式化日期为 ('%Y-%m-%d')
|
|
65
|
+
{ name: :virtual_field, type: :abstract, filter: ->(*) { "#{id}-#{name}" } } # 根据其他字段合成的虚拟字段
|
|
66
|
+
]
|
|
67
|
+
}.freeze
|
|
68
|
+
end
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**实际调用:**
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
user = User.first
|
|
75
|
+
|
|
76
|
+
# 不传参时,默认使用模型中的 INSTANCE_INFO 常量配置
|
|
77
|
+
user.instance_info
|
|
78
|
+
# => { id: 1, user_name: "John", status: "活跃", created_at: "2026-07-28", virtual_field: "1-John" }
|
|
79
|
+
|
|
80
|
+
# 运行时覆盖配置(完美兼容 Ruby 2.x 的 Hash 传参和 Ruby 3.x 的关键字参数)
|
|
81
|
+
user.instance_info(only: [:id, :name])
|
|
82
|
+
# => { id: 1, name: "John" }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. 数据库迁移宏 (TableDefinition)
|
|
86
|
+
|
|
87
|
+
`ActivemodelObjectInfo::TableDefinition` 模块对 ActiveRecord 的 Migration 进行了扩展,让你能够毫不费力地生成审计字段。
|
|
88
|
+
|
|
89
|
+
**在迁移文件中的使用:**
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
class CreateUsers < ActiveRecord::Migration[6.1]
|
|
93
|
+
def change
|
|
94
|
+
create_table :users do |t|
|
|
95
|
+
t.string :name
|
|
96
|
+
|
|
97
|
+
# 1. 批量生成全套生命周期审计字段:
|
|
98
|
+
# 将会自动生成: created_by, created_at, updated_by, updated_at, deleted(int), deleted_by, deleted_at
|
|
99
|
+
t.generate_operations
|
|
100
|
+
|
|
101
|
+
# 2. 或者生成指定的自定义审计字段:
|
|
102
|
+
# 将会自动生成: audit_by (bigint), audit_at (datetime)
|
|
103
|
+
t.operation_columns(:audit)
|
|
104
|
+
|
|
105
|
+
# 3. 甚至高度自定义前后缀:
|
|
106
|
+
# 将会自动生成: my_review_user (bigint), my_review_time (datetime)
|
|
107
|
+
t.operation_columns(:review, operator_prefix: 'my_', operator_suffix: '_user', timestamp_suffix: '_time')
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 3. 软删除机制 (DeletedOperation)
|
|
114
|
+
|
|
115
|
+
`ActivemodelObjectInfo::DeletedOperation` 模块提供了一套开箱即用的软删除功能,并且与 `TableDefinition` 宏生成的底层字段完美契合。
|
|
116
|
+
|
|
117
|
+
**在模型中配置:**
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
class User < ApplicationRecord
|
|
121
|
+
include ActivemodelObjectInfo::DeletedOperation
|
|
122
|
+
|
|
123
|
+
# 可选:如果你的遗留数据库使用了其他命名习惯,可以覆盖以下常量
|
|
124
|
+
# DELETED_FIELD = 'is_deleted'
|
|
125
|
+
# DELETED_VALID_VALUE = false
|
|
126
|
+
# DELETED_INVALID_VALUE = true
|
|
127
|
+
end
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**实际调用:**
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
# 1. 自动查询作用域:
|
|
134
|
+
# 引入该模块后,会自动注入 `default_scope` 隐藏已被删除的记录。
|
|
135
|
+
User.all # 实际执行 => SELECT * FROM users WHERE deleted = 0
|
|
136
|
+
|
|
137
|
+
# 2. 执行软删除:
|
|
138
|
+
user = User.find(1)
|
|
139
|
+
|
|
140
|
+
# 出于安全和审计规范,你【必须】提供执行删除操作的用户 ID (user_id)
|
|
141
|
+
user.soft_delete(user_id: current_user.id)
|
|
142
|
+
# 这一步将自动执行以下操作:
|
|
143
|
+
# - 将 `deleted` 标记设为 1
|
|
144
|
+
# - 将 `deleted_by` 设为 current_user.id
|
|
145
|
+
# - 将 `deleted_at` 设为当前时间 Time.now
|
|
146
|
+
# - 调用 `save` 保存到数据库
|
|
147
|
+
|
|
148
|
+
# 3. 软删除并同时刷新更新时间 (updated_at):
|
|
149
|
+
user.soft_delete(user_id: current_user.id, refresh_updated: true)
|
|
150
|
+
|
|
151
|
+
# 4. 强校验软删除 (底层调用 save!,失败时抛出异常):
|
|
152
|
+
user.soft_delete!(user_id: current_user.id)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## 开发与测试
|
|
156
|
+
|
|
157
|
+
克隆本仓库后,运行 `bin/setup` 安装开发依赖。
|
|
158
|
+
|
|
159
|
+
运行 RSpec 单元测试:
|
|
160
|
+
```bash
|
|
161
|
+
$ bundle exec rspec
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
运行 RuboCop 代码风格静态检查:
|
|
165
|
+
```bash
|
|
166
|
+
$ bundle exec rubocop
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## 开源协议
|
|
170
|
+
|
|
171
|
+
本项目遵循 [MIT License](https://opensource.org/licenses/MIT) 开源协议。
|
|
@@ -4,8 +4,37 @@ module ActivemodelObjectInfo
|
|
|
4
4
|
#
|
|
5
5
|
# 通用的设置操作项相关的模型方法和处理。
|
|
6
6
|
#
|
|
7
|
+
# 核心作用与职责:
|
|
8
|
+
# 提供模型实例数据格式化输出能力。主要用于将 ActiveRecord 或 ActiveModel 的实例安全、灵活地转换为 Hash,
|
|
9
|
+
# 方便后续转化为 JSON 等格式输出给前端,支持字段过滤、重命名、自定义处理及日期格式化。
|
|
10
|
+
#
|
|
11
|
+
# @example 详细使用方法与示例
|
|
12
|
+
# class User
|
|
13
|
+
# include ActivemodelObjectInfo::Base
|
|
14
|
+
# attr_accessor :id, :name, :created_at
|
|
15
|
+
#
|
|
16
|
+
# INSTANCE_INFO = {
|
|
17
|
+
# only: [:id, :name, :created_at],
|
|
18
|
+
# attributes: [
|
|
19
|
+
# :id,
|
|
20
|
+
# { name: :name, as: :user_name },
|
|
21
|
+
# { name: :created_at, format: :date }
|
|
22
|
+
# ]
|
|
23
|
+
# }.freeze
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# user = User.new(id: 1, name: "test", created_at: Time.now)
|
|
27
|
+
# user.instance_info # => { id: 1, user_name: "test", created_at: "2026-07-28" }
|
|
28
|
+
#
|
|
29
|
+
# 核心重要方法:
|
|
30
|
+
# - {#instance_info}:核心输出方法,返回处理后的散列。
|
|
31
|
+
#
|
|
7
32
|
# @author shiner527 <shiner527@hotmail.com>
|
|
8
33
|
#
|
|
34
|
+
# [Changelog]
|
|
35
|
+
# [2026-07-28] 补充完整 YARD 文档及核心注释,重构 instance_info 签名以兼容 Ruby 3.x 关键字参数 (shiner527)
|
|
36
|
+
# [2021-04-19] 创建基础模块,提供 instance_info 数据格式化输出功能 (shiner527)
|
|
37
|
+
#
|
|
9
38
|
module Base
|
|
10
39
|
# ===== 常量定义 =====
|
|
11
40
|
|
|
@@ -25,22 +54,32 @@ module ActivemodelObjectInfo
|
|
|
25
54
|
#
|
|
26
55
|
# 对象信息输出。主要返回给前端一个可用的散列(会被转化为JSON格式)格式的信息并传递给前端。
|
|
27
56
|
#
|
|
28
|
-
# @param [Hash]
|
|
29
|
-
# @
|
|
57
|
+
# @param [Hash] options_hash 设置选项(传统位置参数 Hash),如果传入将被与 keyword_options 合并
|
|
58
|
+
# @param [Hash] keyword_options 设置选项(Ruby 3 关键字参数)
|
|
59
|
+
# @option keyword_options [Array<Symbol, Hash>] :attributes 具体每一项输出的设置数组。每个元素既可以是标识符实例也可以是一个散列实例。
|
|
30
60
|
# 如果是标识符实例,则表示输出该属性。如果是一个散列实例,则按照散列中的设定值去生成对应的内容。
|
|
31
|
-
# @option
|
|
61
|
+
# @option keyword_options [Array<Symbol>] :only 给出具体可以用来输出的字段属性名数组。
|
|
62
|
+
# @option keyword_options [Array<Symbol>] :except 给出需要被排除输出的字段属性名数组。
|
|
63
|
+
# @option keyword_options [String, Symbol] :datetime_format 全局的时间格式设置。
|
|
32
64
|
#
|
|
33
65
|
# @return [Hash] 返回的处理过的该对象的信息散列。
|
|
34
66
|
#
|
|
35
|
-
def instance_info(**
|
|
36
|
-
#
|
|
37
|
-
|
|
67
|
+
def instance_info(options_hash = nil, **keyword_options)
|
|
68
|
+
# 合并传统参数与关键字参数,完美兼容 Ruby 2.x 的 Hash 传参和 Ruby 3.x 的 **kwargs 传参
|
|
69
|
+
options = (options_hash || {}).merge(keyword_options)
|
|
70
|
+
|
|
71
|
+
# 尝试获取当前类上配置的 INSTANCE_INFO 常量作为默认选项
|
|
38
72
|
options = "#{self.class}::INSTANCE_INFO".safe_constantize || {} if options.blank?
|
|
73
|
+
|
|
74
|
+
# 将 options 的 key 转为 symbol,避免传入字符串 key 导致匹配不到
|
|
75
|
+
options = options.deep_symbolize_keys
|
|
76
|
+
|
|
39
77
|
result = {}
|
|
40
|
-
|
|
78
|
+
|
|
79
|
+
# 1. 整理包含字段和排除字段
|
|
41
80
|
only_attributes = (options[:only] || []).map(&:to_sym)
|
|
42
|
-
|
|
43
|
-
#
|
|
81
|
+
|
|
82
|
+
# 默认排除逻辑:如果不特意指定,系统会默认排除 deleted 等敏感字段,防止软删除数据泄漏
|
|
44
83
|
default_deleted_column = ::Constants::Base::TABLE_COLUMN_DELETE_COLUMN rescue 'deleted'
|
|
45
84
|
default_except_attrs = [
|
|
46
85
|
default_deleted_column,
|
|
@@ -48,42 +87,48 @@ module ActivemodelObjectInfo
|
|
|
48
87
|
"#{default_deleted_column}_at",
|
|
49
88
|
]
|
|
50
89
|
except_attributes = (options[:except] || default_except_attrs).map(&:to_sym)
|
|
51
|
-
|
|
90
|
+
|
|
91
|
+
# 2. 从当前类所有属性中计算出最终要输出的属性名集合
|
|
52
92
|
attribute_configs = options[:attributes] || []
|
|
53
|
-
# 计算要输出的参数名称
|
|
54
93
|
output_attributes = attribute_names.map(&:to_sym)
|
|
55
94
|
output_attributes &= only_attributes if only_attributes.present?
|
|
56
95
|
output_attributes -= except_attributes
|
|
57
96
|
|
|
58
|
-
#
|
|
97
|
+
# 3. 遍历并处理属性配置(attribute_configs)
|
|
59
98
|
# 这里保证了要引入的类中含有 attributes 方法,且为 Hash 类型
|
|
99
|
+
|
|
100
|
+
# 补丁:如果传入了 only_attributes,但是 options[:attributes] 是空(即调用方没传),
|
|
101
|
+
# 我们需要将 only_attributes 中的字段视为基础配置,以确保只包含这几个字段的正常输出
|
|
102
|
+
attribute_configs = only_attributes.map { |attr| { name: attr } } if attribute_configs.empty? && only_attributes.present?
|
|
103
|
+
|
|
60
104
|
attribute_configs.each do |attr_config|
|
|
61
|
-
#
|
|
105
|
+
# 根据配置项的类型(Symbol/String 或 Hash)提取字段名称和具体配置
|
|
62
106
|
if [::String, ::Symbol].any? { |attr_class| attr_config.is_a?(attr_class) }
|
|
63
107
|
attribute_name = attr_config.to_sym
|
|
64
108
|
current_attr_config = {}
|
|
65
|
-
elsif attr_config.is_a?(::Hash)
|
|
109
|
+
elsif attr_config.is_a?(::Hash)
|
|
66
110
|
current_attr_config = attr_config.deep_symbolize_keys
|
|
67
111
|
attribute_name = current_attr_config[:name]
|
|
68
|
-
else
|
|
112
|
+
else
|
|
113
|
+
# 如果配置格式非法则直接跳过
|
|
69
114
|
next
|
|
70
115
|
end
|
|
71
|
-
|
|
116
|
+
|
|
117
|
+
# 确定实际取值的属性名,支持通过 as 别名取值
|
|
72
118
|
raw_name = current_attr_config[:as].present? ? current_attr_config[:as].to_sym : attribute_name
|
|
73
|
-
# 过滤器输出字段,如果给定了一个块,则使用用户指定的,否则默认为没有过滤器
|
|
74
119
|
filter = current_attr_config[:filter]
|
|
75
120
|
|
|
76
|
-
#
|
|
121
|
+
# 取出对象中的实际值
|
|
77
122
|
k = raw_name
|
|
78
|
-
#
|
|
123
|
+
# 特殊处理 abstract 类型:当类型为抽象类时,由于可能没有对应的真实属性方法,直接赋值为 nil,后续依赖 filter 来生成实际值
|
|
79
124
|
v = current_attr_config[:type] == :abstract ? nil : __send__(k)
|
|
80
125
|
|
|
81
|
-
#
|
|
82
|
-
# 如果不是要输出的字段则跳过,或者如果不是给出type设置项为 :method 或者 :abstract 也跳过。
|
|
126
|
+
# 跳过条件:既不在最终输出名单中,也不是显式声明的 abstract/method 虚拟字段
|
|
83
127
|
next unless output_attributes.include?(k) || %i[abstract method].include?(current_attr_config[:type])
|
|
84
128
|
|
|
85
|
-
#
|
|
129
|
+
# 4. 根据类型或 filter 对值进行格式化转换
|
|
86
130
|
if filter.present?
|
|
131
|
+
# 如果配置了 filter,通过 Proc、Symbol(调用同名方法) 或 直接常量 的形式进行过滤转换
|
|
87
132
|
result[attribute_name] = case filter
|
|
88
133
|
when ::Proc
|
|
89
134
|
instance_exec(v, &filter)
|
|
@@ -92,28 +137,29 @@ module ActivemodelObjectInfo
|
|
|
92
137
|
else
|
|
93
138
|
filter
|
|
94
139
|
end
|
|
95
|
-
# 如果值是时间类别的字段,默认转换为时间日期格式的字符串
|
|
96
140
|
elsif [::Date, ::Time, ::DateTime].any? { |time_class| v.is_a?(time_class) }
|
|
97
|
-
#
|
|
141
|
+
# 对时间类型的字段进行格式化,优先级:字段级自定义 format > 全局 datetime_format > 默认全格式
|
|
98
142
|
attribute_format = current_attr_config[:format].present? ? current_attr_config[:format] : options[:datetime_format]
|
|
99
|
-
result[attribute_name] = if attribute_format.to_s == 'standard'
|
|
100
|
-
v
|
|
101
|
-
elsif attribute_format.present?
|
|
102
|
-
#
|
|
143
|
+
result[attribute_name] = if attribute_format.to_s == 'standard'
|
|
144
|
+
v # standard 保持时间对象原生格式
|
|
145
|
+
elsif attribute_format.present?
|
|
146
|
+
# 匹配内置的别名格式 (full/min/date/month/year),否则作为自定义 strftime 字符串处理
|
|
103
147
|
if %i[full min date month year].include?(attribute_format.to_sym)
|
|
104
148
|
v.strftime("::#{self.class}::DATETIME_#{attribute_format.to_s.upcase}".constantize)
|
|
105
|
-
else
|
|
149
|
+
else
|
|
106
150
|
v.strftime(attribute_format)
|
|
107
151
|
end
|
|
108
|
-
else
|
|
152
|
+
else
|
|
153
|
+
# 缺省转换为 '%Y-%m-%d %H:%M:%S'
|
|
109
154
|
v.strftime(DATETIME_FULL)
|
|
110
155
|
end
|
|
111
|
-
else
|
|
156
|
+
else
|
|
157
|
+
# 普通值直接赋值
|
|
112
158
|
result[attribute_name] = v
|
|
113
159
|
end
|
|
114
160
|
end
|
|
115
161
|
|
|
116
|
-
#
|
|
162
|
+
# 统一将结果第一层的键名转化为 Symbol 格式并返回
|
|
117
163
|
result.symbolize_keys!
|
|
118
164
|
end
|
|
119
165
|
end
|
|
@@ -4,59 +4,97 @@ module ActivemodelObjectInfo
|
|
|
4
4
|
#
|
|
5
5
|
# 用来进行和删除操作相关的数据库模型的功能模组。主要结合了使用 +:deleted+ 字段标识数据软删除的功能。
|
|
6
6
|
#
|
|
7
|
+
# 核心作用与职责:
|
|
8
|
+
# 为 ActiveRecord 模型提供标准化的“软删除(Soft Delete)”功能。
|
|
9
|
+
# 引入该模块后,会自动通过 `default_scope` 过滤掉已标记为删除的记录,
|
|
10
|
+
# 并注入 `soft_delete` / `soft_delete!` 方法。在执行软删除时,会自动更新
|
|
11
|
+
# 相关的审计字段(如 deleted_by, deleted_at, updated_by)。
|
|
12
|
+
#
|
|
13
|
+
# @example 详细使用方法与示例
|
|
14
|
+
# class User < ApplicationRecord
|
|
15
|
+
# include ActivemodelObjectInfo::DeletedOperation
|
|
16
|
+
#
|
|
17
|
+
# # 可选:覆盖默认的配置常量
|
|
18
|
+
# DELETED_FIELD = 'is_deleted'
|
|
19
|
+
# DELETED_VALID_VALUE = false
|
|
20
|
+
# DELETED_INVALID_VALUE = true
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# # 查询数据时会自动应用 default_scope: WHERE is_deleted = false
|
|
24
|
+
# User.all
|
|
25
|
+
#
|
|
26
|
+
# # 软删除一条记录(必须要传入 user_id)
|
|
27
|
+
# user = User.find(1)
|
|
28
|
+
# user.soft_delete(user_id: current_user.id, refresh_updated: true)
|
|
29
|
+
#
|
|
30
|
+
# 核心重要方法:
|
|
31
|
+
# - {#soft_delete}:执行软删除并调用 save 更新数据。
|
|
32
|
+
# - {#soft_delete!}:执行软删除并调用 save! 更新数据(抛出异常)。
|
|
33
|
+
# - {#delete_block}:底层通用的删除字段赋值逻辑块。
|
|
34
|
+
#
|
|
7
35
|
# @author shiner527 <shiner527@hotmail.com>
|
|
8
36
|
#
|
|
37
|
+
# [Changelog]
|
|
38
|
+
# [2026-07-28] 补充完整 YARD 文档、行内注释,清理尾随空格 (shiner527)
|
|
39
|
+
# [2021-04-19] 创建基础模块,提供软删除与作用域注入功能 (shiner527)
|
|
40
|
+
#
|
|
9
41
|
module DeletedOperation
|
|
10
42
|
extend ::ActiveSupport::Concern
|
|
11
43
|
|
|
12
44
|
# 当被 include 关键字引入后的处理
|
|
13
45
|
included do |_|
|
|
14
|
-
#
|
|
46
|
+
# 1. 提取常量配置:如果宿主类定义了覆盖常量,则使用宿主类的,否则使用默认值
|
|
15
47
|
deleted_field = const_defined?(:DELETED_FIELD) ? DELETED_FIELD : 'deleted'
|
|
16
48
|
deleted_value_valid = const_defined?(:DELETED_VALID_VALUE) ? DELETED_VALID_VALUE : 0
|
|
17
49
|
deleted_value_invalid = const_defined?(:DELETED_INVALID_VALUE) ? DELETED_INVALID_VALUE : 1
|
|
18
|
-
|
|
50
|
+
|
|
51
|
+
# 2. 注入 default_scope 默认查询作用域:如果模型拥有删除标记字段,则默认查询自动排除被标记的数据
|
|
19
52
|
default_scope do
|
|
20
53
|
_current_model = try(:name).to_s.safe_constantize
|
|
21
|
-
where(deleted_field.to_sym => deleted_value_valid) if _current_model.
|
|
54
|
+
where(deleted_field.to_sym => deleted_value_valid) if _current_model.has_attribute?(deleted_field)
|
|
22
55
|
end
|
|
23
56
|
|
|
24
|
-
#
|
|
57
|
+
# 3. 定义底层的删除逻辑块 (给实例对象的内存属性赋值)
|
|
25
58
|
define_method(:delete_block) do |**options|
|
|
26
|
-
#
|
|
59
|
+
# 处理可选项参数:默认不刷新 updated_at 字段
|
|
27
60
|
options[:refresh_updated] = options[:refresh_updated].nil? ? false : options[:refresh_updated]
|
|
28
61
|
|
|
29
|
-
# 必须要传递操作的用户ID
|
|
62
|
+
# 必须要传递操作的用户ID信息,强制审计规范
|
|
30
63
|
raise ArgumentError, 'Must give user id!' if options[:user_id].blank?
|
|
31
64
|
|
|
32
|
-
#
|
|
65
|
+
# 提取字段名配置
|
|
33
66
|
updated_by_field = (options[:updated_by_field] || 'updated_by').to_sym
|
|
34
67
|
deleted_by_field = (options[:deleted_by_field] || 'deleted_by').to_sym
|
|
35
68
|
deleted_at_field = (options[:deleted_at_field] || 'deleted_at').to_sym
|
|
36
|
-
|
|
69
|
+
|
|
70
|
+
# 核心:设置删除状态为已失效标记值
|
|
37
71
|
__send__("#{deleted_field}=", deleted_value_invalid)
|
|
38
|
-
|
|
72
|
+
|
|
73
|
+
# 审计:如果模型存在对应的审计字段,则设置删除人、删除时间,以及根据配置选择性地设置更新人
|
|
39
74
|
__send__("#{deleted_by_field}=", options[:user_id]) if respond_to?(deleted_by_field)
|
|
40
75
|
__send__("#{deleted_at_field}=", Time.now.localtime) if respond_to?(deleted_at_field)
|
|
41
76
|
__send__("#{updated_by_field}=", options[:user_id]) if respond_to?(updated_by_field) && options[:refresh_updated]
|
|
42
77
|
end
|
|
43
78
|
|
|
44
|
-
#
|
|
79
|
+
# 4. 暴露的常规软删除方法 (使用 save 存储,返回 boolean)
|
|
45
80
|
define_method(:soft_delete) do |**options|
|
|
46
81
|
opts = options.deep_symbolize_keys
|
|
47
|
-
#
|
|
82
|
+
# 安全防范:如果没有定义删除标记字段则直接返回,不执行任何操作
|
|
48
83
|
return unless respond_to?(deleted_field)
|
|
84
|
+
|
|
49
85
|
delete_block(**opts)
|
|
50
|
-
|
|
86
|
+
|
|
87
|
+
# 调用 ActiveRecord 内置方法持久化,根据 refresh_updated 参数决定是否让系统自动更新 updated_at
|
|
51
88
|
save(touch: opts[:refresh_updated])
|
|
52
89
|
end
|
|
53
90
|
|
|
54
|
-
#
|
|
91
|
+
# 5. 暴露的强校验软删除方法 (使用 save! 存储,失败抛出异常)
|
|
55
92
|
define_method(:soft_delete!) do |**options|
|
|
56
93
|
opts = options.deep_symbolize_keys
|
|
57
94
|
return unless respond_to?(deleted_field)
|
|
95
|
+
|
|
58
96
|
delete_block(**opts)
|
|
59
|
-
|
|
97
|
+
|
|
60
98
|
save!(touch: opts[:refresh_updated])
|
|
61
99
|
end
|
|
62
100
|
end
|
|
@@ -5,8 +5,38 @@ module ActivemodelObjectInfo
|
|
|
5
5
|
# 重新扩展一些方法,用来方便在创建迁移文件的时候进行一些通用类的设定。
|
|
6
6
|
# 从 @version 0.3.0 开始支持了自动创建的时间戳字段增加索引
|
|
7
7
|
#
|
|
8
|
+
# 核心作用与职责:
|
|
9
|
+
# 在 ActiveRecord 数据库迁移(Migration)建表时,提供便捷的宏方法,
|
|
10
|
+
# 一键生成通用的审计追踪字段(如操作人、操作时间)及软删除字段。
|
|
11
|
+
#
|
|
12
|
+
# @example 详细使用方法与示例
|
|
13
|
+
# class CreateUsers < ActiveRecord::Migration[6.1]
|
|
14
|
+
# def change
|
|
15
|
+
# create_table :users do |t|
|
|
16
|
+
# t.string :name
|
|
17
|
+
#
|
|
18
|
+
# # 示例1: 生成指定的自定义操作字段
|
|
19
|
+
# t.operation_columns(:audit, with_operator: true, operator_prefix: 'my_', operator_suffix: '_user')
|
|
20
|
+
# # => 将会生成 my_audit_user (bigint) 和 audit_at (datetime) 字段
|
|
21
|
+
#
|
|
22
|
+
# # 示例2: 生成常用的创建、更新、删除字段套装
|
|
23
|
+
# t.generate_operations
|
|
24
|
+
# # => 将会生成 created_by, created_at, updated_by, updated_at, deleted_by, deleted_at, 以及 deleted(integer)
|
|
25
|
+
# end
|
|
26
|
+
# end
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# 核心重要方法:
|
|
30
|
+
# - {#operation_columns}:生成指定操作的审计字段(含前缀、后缀配置)。
|
|
31
|
+
# - {#generate_operations}:批量生成创建、更新、删除相关的全套审计字段。
|
|
32
|
+
#
|
|
8
33
|
# @author shiner527 <shiner527@hotmail.com>
|
|
9
34
|
#
|
|
35
|
+
# [Changelog]
|
|
36
|
+
# [2026-07-28] 补充完整 YARD 文档、行内注释,清理尾随空格 (shiner527)
|
|
37
|
+
# [2021-04-20] 支持自动创建的时间戳字段增加索引 (@version 0.3.0) (shiner527)
|
|
38
|
+
# [2021-04-19] 创建基础模块,提供 operation_columns 与 generate_operations (shiner527)
|
|
39
|
+
#
|
|
10
40
|
module TableDefinition
|
|
11
41
|
#
|
|
12
42
|
# 生成操作相关的字段。包含操作人、操作时间等信息。
|
|
@@ -38,21 +68,23 @@ module ActivemodelObjectInfo
|
|
|
38
68
|
#
|
|
39
69
|
def operation_columns(*fields, **options)
|
|
40
70
|
# puts "operation_columns(#{fields}, #{options})"
|
|
41
|
-
#
|
|
71
|
+
# 1. 提取并初始化各种设置选项,对于布尔值优先取用户配置,未配置则默认为 true
|
|
42
72
|
with_operator = options[:with_operator].nil? ? true : options[:with_operator]
|
|
43
73
|
with_timestamp = options[:with_timestamp].nil? ? true : options[:with_timestamp]
|
|
44
74
|
operator_prefix = options[:operator_prefix]
|
|
45
75
|
operator_suffix = options[:operator_suffix] || '_by'
|
|
46
76
|
timestamp_prefix = options[:timestamp_prefix]
|
|
47
77
|
timestamp_suffix = options[:timestamp_suffix] || '_at'
|
|
48
|
-
|
|
78
|
+
|
|
79
|
+
# 2. 遍历每一个需要生成的操作标识符
|
|
49
80
|
fields.each do |field|
|
|
50
|
-
#
|
|
81
|
+
# 3. 动态拼接并生成操作人记录字段 (默认为 bigint 类型并添加索引)
|
|
51
82
|
if with_operator
|
|
52
83
|
operator_column_name = operator_prefix.to_s + field.to_s + operator_suffix.to_s
|
|
53
84
|
column(operator_column_name, :bigint, index: true, comment: '操作人') if operator_column_name.present?
|
|
54
85
|
end
|
|
55
|
-
|
|
86
|
+
|
|
87
|
+
# 4. 动态拼接并生成操作时间戳字段 (默认为 datetime 类型并添加索引)
|
|
56
88
|
if with_timestamp
|
|
57
89
|
timestamp_column_name = timestamp_prefix.to_s + field.to_s + timestamp_suffix.to_s
|
|
58
90
|
column(timestamp_column_name, :datetime, index: true, comment: '操作时间戳') if timestamp_column_name.present?
|
|
@@ -70,10 +102,16 @@ module ActivemodelObjectInfo
|
|
|
70
102
|
def generate_operations(*operations)
|
|
71
103
|
# puts "generate_operations(#{operations})"
|
|
72
104
|
action_fields = operations
|
|
73
|
-
|
|
105
|
+
|
|
106
|
+
# 1. 如果没有给出具体的动作名称,默认配置为创建、更新和删除这三个常规生命周期动作
|
|
74
107
|
action_fields = %w[created updated deleted] if action_fields.empty?
|
|
108
|
+
|
|
109
|
+
# 2. 遍历所有的动作名称以生成相应的字段
|
|
75
110
|
action_fields.each do |operation|
|
|
111
|
+
# 3. 特殊逻辑:当遇到 deleted 动作时,除了生成审计字段外,还需要额外部署一个整型的标记字段,用于承载软删除状态
|
|
76
112
|
column(operation.to_s, :integer, default: 0, comment: '删除标记') if operation.to_sym == :deleted
|
|
113
|
+
|
|
114
|
+
# 4. 复用 operation_columns 方法来生成对应的 xxx_by 操作人和 xxx_at 操作时间字段
|
|
77
115
|
operation_columns(operation)
|
|
78
116
|
end
|
|
79
117
|
end
|
|
@@ -7,9 +7,25 @@ require 'activemodel_object_info/table_definition'
|
|
|
7
7
|
require 'activemodel_object_info/deleted_operation'
|
|
8
8
|
|
|
9
9
|
#
|
|
10
|
-
#
|
|
10
|
+
# 扩展模组主入口。
|
|
11
|
+
#
|
|
12
|
+
# 核心作用与职责:
|
|
13
|
+
# 这是 activemodel-object-info Gem 的主命名空间和入口文件。
|
|
14
|
+
# 它负责统一加载所有相关的依赖库(ActiveSupport)和内部子模块(Base, TableDefinition, DeletedOperation)。
|
|
15
|
+
#
|
|
16
|
+
# @example 详细使用方法
|
|
17
|
+
# require 'activemodel_object_info'
|
|
18
|
+
#
|
|
19
|
+
# 包含的核心模块:
|
|
20
|
+
# - {ActivemodelObjectInfo::Base}:提供模型对象信息格式化输出能力。
|
|
21
|
+
# - {ActivemodelObjectInfo::TableDefinition}:提供数据库迁移时自动生成审计字段的能力。
|
|
22
|
+
# - {ActivemodelObjectInfo::DeletedOperation}:提供记录软删除及其作用域管理的能力。
|
|
11
23
|
#
|
|
12
24
|
# @author shiner527 <shiner527@hotmail.com>
|
|
13
25
|
#
|
|
26
|
+
# [Changelog]
|
|
27
|
+
# [2026-07-28] 补充完整 YARD 文档 (shiner527)
|
|
28
|
+
# [2021-04-19] 创建基础模块结构及入口文件 (shiner527)
|
|
29
|
+
#
|
|
14
30
|
module ActivemodelObjectInfo
|
|
15
31
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activemodel_object_info
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- shiner
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-07-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -156,6 +156,7 @@ files:
|
|
|
156
156
|
- Gemfile.lock
|
|
157
157
|
- LICENSE
|
|
158
158
|
- README.md
|
|
159
|
+
- README.zh-CN.md
|
|
159
160
|
- Rakefile
|
|
160
161
|
- activemodel_object_info.gemspec
|
|
161
162
|
- bin/console
|
|
@@ -185,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
185
186
|
- !ruby/object:Gem::Version
|
|
186
187
|
version: '0'
|
|
187
188
|
requirements: []
|
|
188
|
-
rubygems_version: 3.
|
|
189
|
+
rubygems_version: 3.1.6
|
|
189
190
|
signing_key:
|
|
190
191
|
specification_version: 4
|
|
191
192
|
summary: Build a hash based on active record attributes.
|