arql 0.3.30 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.vscode/launch.json +1 -1
  3. data/Gemfile.lock +1 -1
  4. data/README-zh_CN.org +712 -429
  5. data/README.org +3 -0
  6. data/auto-set-id-before-save-zh_CN.org +1 -1
  7. data/custom-configurations-zh_CN.org +40 -3
  8. data/define-associations-zh_CN.org +31 -17
  9. data/initializer-structure-zh_CN.org +22 -4
  10. data/lib/arql/app.rb +98 -71
  11. data/lib/arql/cli.rb +31 -15
  12. data/lib/arql/commands/info.rb +41 -28
  13. data/lib/arql/commands/models.rb +108 -33
  14. data/lib/arql/commands/reconnect.rb +8 -4
  15. data/lib/arql/commands/redefine.rb +3 -1
  16. data/lib/arql/commands/sandbox.rb +6 -4
  17. data/lib/arql/commands.rb +0 -2
  18. data/lib/arql/concerns/global_data_definition.rb +40 -6
  19. data/lib/arql/concerns/model_extension.rb +168 -0
  20. data/lib/arql/concerns/table_data_definition.rb +20 -20
  21. data/lib/arql/concerns.rb +1 -0
  22. data/lib/arql/definition.rb +169 -317
  23. data/lib/arql/ext/active_record/relation.rb +29 -0
  24. data/lib/arql/ext/active_record/result.rb +29 -0
  25. data/lib/arql/ext/array.rb +40 -1
  26. data/lib/arql/ext/kernel.rb +70 -61
  27. data/lib/arql/ext/object.rb +14 -0
  28. data/lib/arql/ext/ransack/search.rb +29 -0
  29. data/lib/arql/mysqldump.rb +0 -1
  30. data/lib/arql/ssh_proxy.rb +25 -22
  31. data/lib/arql/version.rb +1 -1
  32. data/lib/arql.rb +11 -7
  33. data/ruby-guides-for-java-developer-zh_CN.org +766 -0
  34. data/simple-active-record-guide-zh_CN.org +83 -0
  35. data/simple-pry-guides-zh_CN.org +114 -0
  36. data/sql-log-zh_CN.org +8 -3
  37. metadata +9 -5
  38. data/lib/arql/commands/table.rb +0 -55
  39. data/lib/arql/commands/vd.rb +0 -46
  40. data/lib/arql/connection.rb +0 -16
data/README-zh_CN.org CHANGED
@@ -29,7 +29,6 @@
29
29
  #+end_example
30
30
 
31
31
  ** 使用方法
32
-
33
32
  *** 命令行选项
34
33
 
35
34
  #+begin_example
@@ -73,7 +72,33 @@
73
72
 
74
73
  **** =-e, --env=ENVIRON=
75
74
 
76
- 指定一个在配置文件中的环境名称。
75
+ 指定一个或多个在配置文件中的环境名称,多个环境名称之间用逗号/加号/冒号分隔。
76
+
77
+ Arql 为每个环境所生成的模型类将放在该环境的 =namespace= 配置所指定的命名空间下。例如:
78
+
79
+ #+BEGIN_SRC yaml
80
+ development:
81
+ adapter: mysql2
82
+ host: localhost
83
+ username: root
84
+ database: myapp_development
85
+ pool: 5
86
+ namespace: Dev
87
+ #+END_SRC
88
+
89
+ 假设 =myapp_development= 数据库中有一个名为 =users=, =posts= 等表,那么在 =development= 环境下生成的模型类将是:
90
+
91
+ + =Dev::User=
92
+ + =Dev::Post=
93
+
94
+ 如果没有指定 =namespace= 配置,那么默认的命名空间为环境名称的 CamelCase 形式。例如这里的 =Development=, 那么生成的模型类将是:
95
+
96
+ + =Development::User=
97
+ + =Development::Post=
98
+
99
+ Arql 通过覆盖 =Object.const_missing= 的方式,为那些类名和已有常量不重名的模型类,在顶层命名空间下也定义了一个「别名」,例如在不和已有常量重名的情况下,可以直接使用 =User=, =Post= 等类名。
100
+
101
+ 如果指定的多个环境中有重名的表,那么按照指定的环境的顺序,将为前面的环境中的表的模型类定义一个「别名」
77
102
 
78
103
  **** =-E, --eval=CODE=
79
104
 
@@ -166,6 +191,28 @@
166
191
  6. =ssh.password= : ssh 密码
167
192
  7. =ssh.local_port= : ssh 本地端口
168
193
  8. =singularized_table_names=: 是否使用单数表名,默认为 =false=, 如果为 =false=, 则 =students= 表将定义为 =Student= 模型,如果为 =true=, 则 =students= 表将定义为 =Students= 模型
194
+ 9. =table_name_prefixes=: 表名前缀数组,默认为空数组,如果指定了此项,在生成模型时将忽略这些前缀,例如,如果指定了 =["t_"]=, 则 =t_students= 表将定义为 =Student= 模型
195
+ 10. =namespace=: 模型命名空间,默认为环境名称的 CamelCase 形式,生成的模型将放在指定的命名空间下
196
+ 11. =model_names=: 这个配置项的值是一个 Hash(Map) , Key 为表名, Value 为将要为该表生成的模型名称; Arql 默认使用
197
+ ActiveRecord 的命名规则生成模型名称,如果指定了这个配置项,该配置项所指定的表将使用改配置项指定的模型名称Value
198
+ 除了可以是表示模型名称的字符串外,还可以是一个字符串数组,数组的第一个元素表示模型名称,第二个元素表示为该模型创
199
+ 建的常量别名(Arql 默认也会按照一定的规则自动为生成的模型类创建别名,如果这里指定了别名,将会使用用户提供的值作
200
+ 为别名)
201
+
202
+ =model_names= 配置项的例子:
203
+
204
+ #+BEGIN_SRC yaml
205
+ development:
206
+ host: localhost
207
+ database: test
208
+ username: root
209
+ model_names:
210
+ students: Seito
211
+ teachers: ["LaoShi", "LS"]
212
+ #+END_SRC
213
+
214
+ 以上配置文件中,将为 =students= 表生成一个名为 =Seito= 的模型,为 =teachers= 表生成一个名为 =LaoShi= 的模型,并为该模型创建一个名为 =LS= 的常量别名;
215
+ 还会为 =students= 表生成一个别名: =S=
169
216
 
170
217
  **** 配置文件示例
171
218
 
@@ -182,7 +229,9 @@
182
229
  username: root
183
230
  database: blog
184
231
  password:
232
+ table_name_prefixes: ["t_"]
185
233
  socket: /tmp/mysql.sock
234
+ namespace: B
186
235
 
187
236
  dev:
188
237
  <<: *default
@@ -191,6 +240,8 @@
191
240
  username: root
192
241
  password: 123456
193
242
  database: blog
243
+ table_name_prefixes: ["t_"]
244
+ namespace: B
194
245
  ssh:
195
246
  host: dev.mycompany.com
196
247
  port: 22
@@ -224,7 +275,7 @@
224
275
  =info= 命令打印当前的数据库连接信息和 SSH 代理信息,例如:
225
276
 
226
277
  #+begin_example
227
- Database Connection Information:
278
+ my_env Database Connection Information:
228
279
  Host:
229
280
  Port:
230
281
  Username: root
@@ -235,6 +286,12 @@
235
286
  Pool Size: 5
236
287
  #+end_example
237
288
 
289
+ =info= 默认显示指定的所有环境的连接信息,如果只想显示当前环境的连接信息, =info= 命令接受一个正则表达式参数,只显示匹配的环境信息,例如:
290
+
291
+ #+BEGIN_EXAMPLE
292
+ info .*dev
293
+ #+END_EXAMPLE
294
+
238
295
  **** =m= 或者 =l=
239
296
 
240
297
  =m= (或者 =l= ) 命令打印所有表名及对应的模型类名和缩写类名,例如:
@@ -262,9 +319,24 @@
262
319
  - =Abbr= : 缩写类名
263
320
  - =Comment= : 注释
264
321
 
265
- =m= / =l= 命令还可以接受一个参数,用于通过表名或表注释来对列表进行过滤, 例如:
322
+ =m= / =l= 命令三个可选的选项:
323
+
324
+ + =-e=, =--env= : 指定环境,正则表达式,只显示匹配的环境下的表名,默认显示所有环境
325
+ + =-f=, =--format= : 输出格式:
326
+ - =terminal= : 默认的表格格式
327
+ - =md= : markdown 表格格式
328
+ - =org= : org mode 表格格式
329
+ - =sql= : 输出 create table SQL
330
+ + =-c=, =--column= : 正则表达式,列出字段,而不是表,按照字段名或字段注释筛选
266
331
 
267
- =m perm= 只会列出表名或表注释中包含 =perm= 的表;如果要使用正则表达式匹配,可以使用 =m /perm/i= 来进行匹配。
332
+ =m= / =l= 命令还可以接受一个可选的正则表达式参数,只显示(按照表名或表注释)匹配的表的信息,例如:
333
+
334
+ #+BEGIN_EXAMPLE
335
+ l # 显示所有表的信息
336
+ l ^post # 只显示表名以 post 开头的表的信息
337
+ l -e dev -f md # 显示 dev 环境下的表信息,并以 markdown 格式输出
338
+ l -c no|num # 只显示字段名、字段注释中包含 no 或 num 的字段信息
339
+ #+END_EXAMPLE
268
340
 
269
341
  **** =t=
270
342
 
@@ -346,9 +418,9 @@
346
418
  =redefine= 命令用于重新定义 ActiveRecord 模型类,根据数据库表的信息重新生成模型类。对于在 =init.rb= 中添加了新的关
347
419
  系定义,想使新定义的关系在当前 Pry 会话中生效,可以使用 =redefine= 命令。
348
420
 
349
- **** 沙盒模式
421
+ **** =sandbox-enter= 和 =sandbox-quit=
350
422
 
351
- =sandbox-enter= 命令用于开启沙盒模式。在沙盒模式下,所有的数据库操作都会在事务中执行,该事务不会自动提交,需要手动提交或回滚。
423
+ =sandbox-enter= 命令用于开启沙盒模式。在沙盒模式下,所有的数据库操作都会在事务中执行,该事务不会自动提交,退出沙盒模式时,会自动回滚事务。
352
424
 
353
425
  1. 开启沙盒模式:
354
426
  #+begin_example
@@ -358,19 +430,7 @@
358
430
  2. 退出沙盒模式:
359
431
  #+begin_example
360
432
  ARQL@demo247 [sandbox] (main) [7] ❯ sandbox-quit
361
- begin_transaction callbacks removed.
362
- You still have open 1 transactions open, don't forget commit or rollback them.
363
- #+end_example
364
- 3. 提交事务:
365
- #+begin_example
366
- ARQL@demo247(main) [7] ❯ $C.commit_transaction
367
433
  #+end_example
368
- 4. 回滚事务:
369
- #+begin_example
370
- ARQL@demo247(main) [7] ❯ $C.rollback_transaction
371
- #+end_example
372
-
373
-
374
434
 
375
435
  *** 作为代码解释器使用
376
436
 
@@ -408,23 +468,79 @@
408
468
  $ echo 'puts Person.count' | arql -e dev
409
469
  #+end_example
410
470
 
411
- *** 额外的扩展方法
412
- **** =to_insert_sql= / =to_upsert_sql=
413
-
414
- 可以在任何 ActiveRecord 模型实例上调用 =to_insert_sql= / =to_upsert_sql= 方法,获取该对象的插入或更新 SQL 语句。
415
- 这两个方法也可以在包含 ActiveRecord 模型实例对象的数组对象上调用。
471
+ ** 额外的扩展方法
472
+ *** 命名空间模块的模块方法
473
+ **** =q=
416
474
 
475
+ =q= 用于执行 SQL 查询
476
+
417
477
  #+begin_example
418
- ARQL ❯ Person.all.to_a.to_insert_sql
419
- => "INSERT INTO `person` (`id`,`name`,`age`,`gender`,`grade`,`blood_type`) VALUES (1, 'Jack', 30, NULL, NULL, NULL), (2, 'Jack', 11, 1, NULL, NULL), (3, 'Jack', 12, 1, NULL, NULL), (4, 'Jack', 30, 1, NULL, NULL), (5, 'Jack', 12, 2, NULL, NULL), (6, 'Jack', 2, 2, 2, NULL), (7, 'Jack', 3, 2, 2, NULL), (8, 'Jack', 30, 2, 2, 'AB'), (9, 'Jack', 30, 2, 2, 'AB'), (10, 'Jack', 30, 2, 2, 'AB'), (11, 'Jackson', 30, 2, 2, 'AB') ON DUPLICATE KEY UPDATE `id`=`id`;"
478
+ ARQL ❯ rs = Blog::q 'select count(0) from person;'
479
+ => #<ActiveRecord::Result:0x00007fd1f8026ad0 @column_types={}, @columns=["count(0)"], @hash_rows=nil, @rows=[[11]]>
480
+ ARQL ❯ rs.rows
481
+ => [[11]]
420
482
  #+end_example
483
+ **** =models=
484
+
485
+ =models= 返回该命名空间下的所有模型类
486
+
487
+ #+begin_example
488
+ ARQL ❯ Blog::models
489
+ => [Blog::Person(id: integer, name: string, age: integer, created_at: datetime, updated_at: datetime), Blog::Post(id: integer, title: string, content: text, created_at: datetime, updated_at: datetime)]
490
+ #+end_example
491
+
492
+ **** =tables=
493
+
494
+ =tables= 返回该命名空间下的所有表名
495
+
496
+ #+begin_example
497
+ ARQL ❯ Blog::tables
498
+ => ["people", "posts"]
499
+ #+end_example
500
+
501
+ **** =model_names=
502
+
503
+ =model_names= 返回该命名空间下的所有模型类的名称
504
+
505
+ #+begin_example
506
+ ARQL ❯ Blog::model_names
507
+ => ["Demo::Person", "Demo::Post"]
508
+ #+end_example
509
+
510
+ **** =create_table=
511
+
512
+ =create_table= 用于在该命名空间所对应的环境中创建表
513
+
514
+ #+begin_example
515
+ ARQL ❯ Blog::create_table :people do |t|
516
+ ARQL ❯ t.string :name
517
+ ARQL ❯ t.integer :age
518
+ ARQL ❯ t.timestamps
519
+ ARQL ❯ end
520
+ #+end_example
521
+
522
+ **** =dump=
523
+
524
+ =dump= 通过 =mysqldump= 将该命名空间对应的数据库导出到指定的文件中
525
+
526
+ #+begin_example
527
+ ARQL ❯ Blog::dump('~/data/blog.sql')
528
+ #+end_example
529
+
530
+ *** 模型的类方法
531
+
532
+ Pry 内建了 =show-source= (别名 =$= ) 和 =show-doc= (别名 =?= )命令,可以查看方法的源码和文档。可以通过 =show-doc= 查看方法的文档。例如:
421
533
 
534
+ #+BEGIN_EXAMPLE
535
+ ARQL ❯ ? Student.add_column
536
+ #+END_EXAMPLE
537
+
422
538
  **** =to_create_sql=
423
539
 
424
540
  可以在任何 ActiveRecord 模型类上调用 =to_create_sql= 方法,获取该模型类对应的表的创建 SQL 语句。
425
541
 
426
542
  #+begin_example
427
- ARQL@demo247(main) [16] ❯ puts Post.to_create_sql
543
+ ARQL@demo247(main) [16] ❯ puts Blog::Post.to_create_sql
428
544
  D, [2024-04-07T14:15:11.106693 #20440] DEBUG -- : SQL (24.9ms) show create table post
429
545
  CREATE TABLE `post` (
430
546
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
@@ -440,6 +556,167 @@
440
556
  ) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
441
557
  #+end_example
442
558
 
559
+ **** =t=
560
+
561
+ =t= 类方法用于打印模型类的表结构
562
+
563
+ 执行 =Blog::Person.t= 命令会打印 =person= 表的定义信息:
564
+
565
+ #+begin_example
566
+ Table: person
567
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
568
+ | PK | Name | SQL Type | Ruby Type | Limit | Precision | Scale | Default | Nullable | Comment |
569
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
570
+ | Y | id | int(11) unsigned | integer | 4 | | | | false | |
571
+ | | name | varchar(64) | string | 64 | | | | true | |
572
+ | | age | int(11) | integer | 4 | | | | true | |
573
+ | | gender | int(4) | integer | 4 | | | | true | |
574
+ | | grade | int(4) | integer | 4 | | | | true | |
575
+ | | blood_type | varchar(4) | string | 4 | | | | true | |
576
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
577
+ #+end_example
578
+
579
+ =t= 接受一个可选的 =format= 命名参数,可选值为:
580
+
581
+ + =md=
582
+ + =org=
583
+ + =sql=
584
+ + =terminal= (默认值)
585
+
586
+ 例如:
587
+
588
+ #+begin_example
589
+ ARQL ❯ Blog::Person.t :sql
590
+ #+end_example
591
+
592
+ 输出:
593
+
594
+ #+begin_example
595
+ CREATE TABLE `person` (
596
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
597
+ `name` varchar(64) DEFAULT NULL,
598
+ `age` int(11) DEFAULT NULL,
599
+ `gender` int(4) DEFAULT NULL,
600
+ `grade` int(4) DEFAULT NULL,
601
+ `blood_type` varchar(4) DEFAULT NULL,
602
+ PRIMARY KEY (`id`)
603
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='人员表';
604
+ #+end_example
605
+
606
+ **** =v=
607
+
608
+ =v= 类方法用于和 Emacs 的 org babel 集成,可以在 org 文件中直接调用 =v= 方法,获取模型类的表结构。
609
+
610
+ 例如:
611
+
612
+ #+begin_example
613
+ ARQL ❯ Blog::Post.v
614
+ #+end_example
615
+
616
+ 输出:
617
+
618
+ #+BEGIN_EXAMPLE
619
+ ARQL@demo247(main) [10] ❯ Demo::Post.v
620
+ => [["PK", "Name", "SQL Type", "Ruby Type", "Limit", "Precision", "Scale", "Default", "Nullable", "Comment"],
621
+ nil,
622
+ ["Y", "id", "int(10) unsigned", :integer, 4, "", "", "", false, "ID"],
623
+ ["", "name", "varchar(256)", :string, 256, "", "", "", true, ""],
624
+ ["", "gender", "varchar(256)", :string, 256, "", "", "", true, ""],
625
+ ["", "phone", "varchar(256)", :string, 256, "", "", "", true, ""],
626
+ ["", "id_no", "varchar(256)", :string, 256, "", "", "", true, ""],
627
+ ["", "note", "varchar(256)", :string, 256, "", "", "", true, ""],
628
+ ["", "gmt_created", "datetime", :datetime, "", 0, "", "", false, "创建时间"],
629
+ ["", "gmt_modified", "datetime", :datetime, "", 0, "", "", false, "最后修改时间"],
630
+ ["", "sasa", "varchar(255)", :string, 255, "", "", "", true, ""]]
631
+ #+END_EXAMPLE
632
+
633
+ **** =vd=
634
+
635
+ 使用 =visidata= 显示表结构
636
+ **** =table_comment=
637
+
638
+ 返回该模型的表注释
639
+
640
+ 例如:
641
+
642
+ #+begin_example
643
+ ARQL ❯ Blog::Post.table_comment
644
+ #+end_example
645
+
646
+ 输出:
647
+
648
+ #+begin_example
649
+ "文章表"
650
+ #+end_example
651
+
652
+ **** 添加字段 =add_column=
653
+ #+BEGIN_EXAMPLE
654
+ Blog::Student.add_column :note, :text, comment: '备注'
655
+ #+END_EXAMPLE
656
+
657
+ **** 修改字段 =change_column=
658
+ #+BEGIN_EXAMPLE
659
+ Blog::Student.change_column :note, :string, comment: '备注'
660
+ #+END_EXAMPLE
661
+
662
+ **** 删除字段 =remove_column=
663
+ #+BEGIN_EXAMPLE
664
+ Blog::Student.remove_column :note
665
+ #+END_EXAMPLE
666
+
667
+ **** 添加索引 =add_index=
668
+ #+BEGIN_EXAMPLE
669
+ Blog::Student.add_index :name
670
+ Blog::Student.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
671
+ #+END_EXAMPLE
672
+
673
+ **** 修改字段注释 =change_column_comment=
674
+ #+BEGIN_EXAMPLE
675
+ Blog::Student.change_column_comment :note, '备注'
676
+ #+END_EXAMPLE
677
+
678
+ **** 修改字段默认值 =change_column_default=
679
+ #+BEGIN_EXAMPLE
680
+ Blog::Student.change_column_default :note, '默认值'
681
+ #+END_EXAMPLE
682
+
683
+ **** 修改字段名称 =rename_column=
684
+ #+BEGIN_EXAMPLE
685
+ Blog::Student.rename_column :note, :remark
686
+ #+END_EXAMPLE
687
+
688
+ **** 修改表名 =rename_table=
689
+ #+BEGIN_EXAMPLE
690
+ Blog::Student.rename_table :seitou
691
+ #+END_EXAMPLE
692
+
693
+ **** 修改表注释 =change_table_comment=
694
+ #+BEGIN_EXAMPLE
695
+ Blog::Student.change_table_comment from: '', to: '学生表'
696
+ #+END_EXAMPLE
697
+
698
+ **** 删除表 =drop_table=
699
+ #+BEGIN_EXAMPLE
700
+ Blog::Student.drop_table
701
+ #+END_EXAMPLE
702
+
703
+ **** 删除索引 =remove_index=
704
+ #+BEGIN_EXAMPLE
705
+ Blog::Student.remove_index :age
706
+ Blog::Student.remove_index name: 'by_branch_party'
707
+ #+END_EXAMPLE
708
+
709
+ **** 查询表注释 =table_comment=
710
+ #+BEGIN_EXAMPLE
711
+ Blog::Student.table_comment
712
+ #+END_EXAMPLE
713
+
714
+ **** 列出表的索引 =indexes=
715
+ #+BEGIN_EXAMPLE
716
+ Blog::Student.indexes
717
+ #+END_EXAMPLE
718
+
719
+ *** 模型的实例方法
443
720
  **** =t=
444
721
 
445
722
  =t= 除了可以作为类方法在 ActiveRecord 模型类上调用,也可以作为实例方法在 ActiveRecord 模型实例对象上调用。
@@ -460,22 +737,31 @@
460
737
 
461
738
  =t= 方法可以接受以下两个选项:
462
739
 
463
- + =:except= 选项,用于指定不显示的属性名,值可以是字符串或正则表达式,例如:
464
- #+BEGIN_EXAMPLE
465
- Person.last.t(except: 'id')
466
- Student.where(condition).t(except: /id|name/)
467
- #+END_EXAMPLE
468
740
  + =:compact= 选项,用于指定是否紧凑显示,值可以是 =true= 或 =false= ,如果启用紧凑显示,那些值全部为 =NULL= 的列将不
469
741
  会显示,这对于查看那些数据稀疏的表很有帮助,例如:
470
742
  #+BEGIN_EXAMPLE
471
743
  Person.last.t(compact: true)
472
744
  Student.where(condition).t(compact: false)
473
745
  #+END_EXAMPLE
746
+ + =:format= 选项,用于指定输出格式,值可以是:
747
+ - =:terminal= 默认的输出格式,适合在终端中查看
748
+ - =:org= org-mode 表格格式
749
+ - =:md= markdown 表格格式
750
+
751
+ **** =to_insert_sql= / =to_upsert_sql=
752
+
753
+ 可以在任何 ActiveRecord 模型实例上调用 =to_insert_sql= / =to_upsert_sql= 方法,获取该对象的插入或更新 SQL 语句。
754
+ 这两个方法也可以在包含 ActiveRecord 模型实例对象的数组对象上调用。
755
+
756
+ #+begin_example
757
+ ARQL ❯ Person.all.to_a.to_insert_sql
758
+ => "INSERT INTO `person` (`id`,`name`,`age`,`gender`,`grade`,`blood_type`) VALUES (1, 'Jack', 30, NULL, NULL, NULL), (2, 'Jack', 11, 1, NULL, NULL), (3, 'Jack', 12, 1, NULL, NULL), (4, 'Jack', 30, 1, NULL, NULL), (5, 'Jack', 12, 2, NULL, NULL), (6, 'Jack', 2, 2, 2, NULL), (7, 'Jack', 3, 2, 2, NULL), (8, 'Jack', 30, 2, 2, 'AB'), (9, 'Jack', 30, 2, 2, 'AB'), (10, 'Jack', 30, 2, 2, 'AB'), (11, 'Jackson', 30, 2, 2, 'AB') ON DUPLICATE KEY UPDATE `id`=`id`;"
759
+ #+end_example
474
760
 
475
761
  **** =v=
476
762
 
477
763
  =v= 方法用于与 Emacs org babel 集成。
478
-
764
+
479
765
  ***** =v= 作为模型类的实例方法
480
766
 
481
767
  在任何 ActiveRecord 模型实例对象上调用 =v= 方法,可以打印一个数组,数组的第一个元素是 =['Attribute Name',
@@ -521,530 +807,537 @@
521
807
  => [[:name, :age], nil, ["Jack", 10], ["Lucy", 20]]
522
808
  #+end_example
523
809
 
524
- **** =q=
525
810
 
526
- #+begin_example
527
- ARQL ❯ rs = q 'select count(0) from person;'
528
- => #<ActiveRecord::Result:0x00007fd1f8026ad0 @column_types={}, @columns=["count(0)"], @hash_rows=nil, @rows=[[11]]>
529
- ARQL ❯ rs.rows
530
- => [[11]]
531
- #+end_example
811
+ **** =dump=
532
812
 
533
- **** JSON 转换和格式化
534
-
535
- 在任何对象上调用 =j= 方法,可以得到 JSON 格式的字符串,调用 =jj= 方法可以得到格式化后的 JSON 字符串。
813
+ 将实例对象导出为 =INSERT= SQL 语句,见下文 「dump 数据」章节
536
814
 
537
- 使用 =jp= 方法打印 JSON,使用 =jjp= 方法打印格式化后的 JSON。
815
+ **** =write_excel= / =write_csv=
538
816
 
539
- **** $C 全局变量
817
+ 将实例对象导出为 Excel 或 CSV 文件,见下文 「读写 Excel 和 CSV 文件」章节
818
+
819
+ *** =ActiveRecord::Relation= / =ActiveRecord::Result= / =Ransack::Search= / =Array= 上的一些通用扩展方法
820
+ =ActiveRecord::Relation= / =ActiveRecord::Result= / =Ransack::Search= 在逻辑上都可以看成是数组,所以这些方法都可以在这些对象上调用:
821
+ **** =t=
540
822
 
541
- Arql =ActiveRecord::Base.connection= 对象赋值给全局可用的 =$C= 全局变量,它代表当前的数据库连接。
823
+ =t= 方法还可以在包含 ActiveRecord 实例的数组上调用,也可以在 =ActiveRecord::Relation= / =ActiveRecord::Result= / =Ransack::Search= 对象上调用。
824
+
825
+ #+begin_example
826
+ ARQL ❯ Person.last.t
827
+ +----------------|-----------------|------------------|---------+
828
+ | Attribute Name | Attribute Value | SQL Type | Comment |
829
+ +----------------|-----------------|------------------|---------+
830
+ | id | 11 | int(11) unsigned | |
831
+ | name | Jackson | varchar(64) | |
832
+ | age | 30 | int(11) | |
833
+ | gender | 2 | int(4) | |
834
+ | grade | 2 | int(4) | |
835
+ | blood_type | AB | varchar(4) | |
836
+ +----------------|-----------------|------------------|---------+
837
+ #+end_example
542
838
 
543
- 上文中的 =q= 方法实际上是 =$C.exec_query= 方法, =$C= 对象的其他方法也很有用:
839
+ 作为数组和「类数组」对象实例方法时, =t= 方法可以接受多个用于过滤属性的参数,参数的类型可以是:
544
840
 
545
- ***** 创建表
546
- #+begin_example
547
- ARQL ❯ $C.create_table :post, id: false, primary_key: :id do |t|
548
- ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
549
- ARQL ❯ t.column :name, :string, comment: '名称'
550
- ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
551
- ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
552
- ARQL ❯ end
553
- #+end_example
841
+ + 字符串或 Symbol,对属性进行字面量匹配
842
+ + 正则表达式,对属性进行正则匹配
554
843
 
555
- =create_table= 同样也被加入到 =Kernel= 下面,所以也可以直接调用 =create_table= 方法:
844
+ 例如, 只显示 =name=, =age= 以及所有名称包含 =time= 字样的属性:
556
845
 
557
846
  #+begin_example
558
- ARQL ❯ create_table :post, id: false, primary_key: :id do |t|
559
- ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
560
- ARQL ❯ t.column :name, :string, comment: '名称'
561
- ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
562
- ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
563
- ARQL ❯ end
847
+ ARQL ❯ Person.last(10).t('name', :age, /time/i)
564
848
  #+end_example
565
-
566
- ***** 添加字段
567
849
 
568
- #+begin_example
569
- $C.add_column :post, :note, :string, comment: '备注'
570
- #+end_example
850
+ 作为数组和「类数组」对象的实例方法的 =t= 还可以接受以下三个选项:
571
851
 
572
- =add_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =add_column= 方法:
852
+ + =:except= 选项,用于指定不显示的属性名,值可以是字符串或正则表达式,例如:
853
+ #+BEGIN_EXAMPLE
854
+ Person.last(10).t(except: 'id')
855
+ Student.where(condition).t(except: /id|name/)
856
+ #+END_EXAMPLE
857
+ + =:compact= 选项,用于指定是否紧凑显示,值可以是 =true= 或 =false= ,如果启用紧凑显示,那些值全部为 =NULL= 的列将不
858
+ 会显示,这对于查看那些数据稀疏的表很有帮助,例如:
859
+ #+BEGIN_EXAMPLE
860
+ Person.last(10).t(compact: true)
861
+ Student.where(condition).t(compact: false)
862
+ #+END_EXAMPLE
863
+ + =:format= 选项,用于指定输出格式,值可以是:
864
+ - =:terminal= 默认的输出格式,适合在终端中查看
865
+ - =:org= org-mode 表格格式
866
+ - =:md= markdown 表格格式
573
867
 
868
+ **** =v=
869
+ =v= 方法用于与 Emacs org babel 集成。
870
+
574
871
  #+begin_example
575
- Post.add_column :note, :string, comment: '备注'
872
+ ARQL Person.last.v
873
+ => [["Attribute Name", "Attribute Value", "SQL Type", "Comment"],
874
+ nil,
875
+ ["id", 11, "int(11) unsigned", ""],
876
+ ["name", "Jackson", "varchar(64)", ""],
877
+ ["age", 30, "int(11)", ""],
878
+ ["gender", 2, "int(4)", ""],
879
+ ["grade", 2, "int(4)", ""],
880
+ ["blood_type", "AB", "varchar(4)", ""]]
576
881
  #+end_example
882
+ **** =vd=
577
883
 
578
- ***** 修改字段
579
-
580
- #+begin_example
581
- $C.change_column :post, :note, :text, comment: '备注'
582
- #+end_example
884
+ 使用 =visidata= 显示「数组」数据
885
+
886
+ **** =write_csv= / =write_excel=
887
+
888
+ =write_csv= 和 =write_excel= 用于将「数组」数据导出为 CSV 或 Excel 文件,见下文 「读写 Excel 和 CSV 文件」章节
889
+
890
+ **** =dump=
583
891
 
584
- =change_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =change_column= 方法:
892
+ =dump= 方法用于将 ActiveRecord::Relation / ActiveRecord::Result / Ransack::Search 对象导出为 INSERT SQL 语句,见下文 「dump 数据」章节
893
+
894
+ *** =Kernel= 扩展方法
585
895
 
586
- #+begin_example
587
- Post.change_column :note, :text, comment: '备注'
588
- #+end_example
896
+ 下列对应某种 DDL 操作的方法,在使用时都有一个限制:如果连接了多个环境,那么在调用这些方法时,必须通过 =:env= 选项指定环境名。例如:
589
897
 
590
- ***** 删除字段
898
+ #+BEGIN_SRC ruby
899
+ create_table :users, env: 'development', comment: '用户表' do |t|
900
+ t.string :name, comment: '姓名'
901
+ t.integer :age, comment: '年龄'
902
+ end
903
+ #+END_SRC
904
+
905
+ **** 创建表 =create_table=
906
+ #+BEGIN_EXAMPLE
907
+ create_table :post, id: false, primary_key: :id do |t|
908
+ t.column :id, :bigint, precison: 19, comment: 'ID'
909
+ t.column :name, :string, comment: '名称'
910
+ t.column :gmt_created, :datetime, comment: '创建时间'
911
+ t.column :gmt_modified, :datetime, comment: '最后修改时间'
912
+ end
913
+ #+END_EXAMPLE
914
+ **** 创建多对多关系的中间表 =create_join_table=
915
+ #+BEGIN_EXAMPLE
916
+ create_join_table :products, :categories do |t|
917
+ t.index :product_id
918
+ t.index :category_id
919
+ end
920
+ #+END_EXAMPLE
921
+ **** 删除表 =drop_table=
922
+ #+BEGIN_EXAMPLE
923
+ drop_table :post
924
+ #+END_EXAMPLE
925
+ **** 删除多对多关系的中间表 =drop_join_table=
926
+ #+BEGIN_EXAMPLE
927
+ drop_join_table :products, :categories
928
+ #+END_EXAMPLE
929
+ **** 修改表名 =rename_table=
930
+ #+BEGIN_EXAMPLE
931
+ rename_table :post, :posts
932
+ #+END_EXAMPLE
591
933
 
592
- #+begin_example
593
- $C.remove_column :post, :note
594
- #+end_example
934
+
935
+ **** =models=
595
936
 
596
- =remove_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =remove_column= 方法:
937
+ 返回将所有环境命名空间下的模型类
597
938
 
598
- #+begin_example
599
- Post.remove_column :note
600
- #+end_example
939
+ **** =table_names=
601
940
 
602
- ***** 删除表
603
-
604
- #+begin_example
605
- $C.drop_table :post
606
- #+end_example
941
+ 返回所有环境下的表名
607
942
 
608
- =drop_table= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =drop_table= 方法:
943
+ **** =model_names=
609
944
 
610
- #+begin_example
611
- Post.drop_table
612
- #+end_example
945
+ 返回所有环境下的模型类名
613
946
 
614
- ***** 添加索引
615
-
616
- #+begin_example
617
- ARQL ❯ $C.add_index :post, :name
618
- ARQL ❯ $C.add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party')
619
- #+end_example
947
+ **** =q=
948
+
949
+ 如果只指定了一个环境,那么可以直接使用 =q= 方法来执行原生 SQL 查询,而不需要在 =q= 前面指定命名空间模块,如 =Blog::q=
950
+
951
+ *** 其它扩展方法
952
+ **** JSON 转换和格式化
953
+
954
+ 在任何对象上调用 =j= 方法,可以得到 JSON 格式的字符串,调用 =jj= 方法可以得到格式化后的 JSON 字符串。
620
955
 
621
- =add_index= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =add_index= 方法:
956
+ 使用 =jp= 方法打印 JSON,使用 =jjp= 方法打印格式化后的 JSON。
957
+
958
+ **** =String=
959
+
960
+ ***** =Srting#p=
961
+
962
+ =p= 方法的定义如下:
622
963
 
623
964
  #+begin_example
624
- Post.add_index :name
625
- Post.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
965
+ class String
966
+ def p
967
+ puts self
968
+ end
969
+ end
626
970
  #+end_example
627
971
 
628
- **** =Kernel= 扩展方法
629
-
630
- =Kernel= 模块下的函数可以想语言内置函数一样直接调用,不需要指定模块名。 以下是 Arql 扩展的 =Kernel= 方法:
972
+ =​"hello".p= 等价于 =puts "hello"​= 。
631
973
 
632
- Pry 内建了 =show-source= (别名 =$= ) 和 =show-doc= (别名 =?= )命令,可以查看方法的源码和文档。可以通过 =show-doc= 查看方法的文档。例如:
974
+ ***** =String#parse=
633
975
 
634
- #+BEGIN_EXAMPLE
635
- ARQL ❯ ? create_table
636
- #+END_EXAMPLE
976
+ 对于一个表示文件路径的字符串,可以调用 =parse= 方法通过文件路径中的后缀名来分别对 Excel、CSV、JSON 文件进行解析。
637
977
 
638
-
639
- ***** 创建表 =create_table=
640
978
  #+BEGIN_EXAMPLE
641
- create_table :post, id: false, primary_key: :id do |t|
642
- t.column :id, :bigint, precison: 19, comment: 'ID'
643
- t.column :name, :string, comment: '名称'
644
- t.column :gmt_created, :datetime, comment: '创建时间'
645
- t.column :gmt_modified, :datetime, comment: '最后修改时间'
646
- end
647
- #+END_EXAMPLE
648
- ***** 创建多对多关系的中间表 =create_join_table=
649
- #+BEGIN_EXAMPLE
650
- create_join_table :products, :categories do |t|
651
- t.index :product_id
652
- t.index :category_id
653
- end
654
- #+END_EXAMPLE
655
- ***** 删除表 =drop_table=
656
- #+BEGIN_EXAMPLE
657
- drop_table :post
658
- #+END_EXAMPLE
659
- ***** 删除多对多关系的中间表 =drop_join_table=
660
- #+BEGIN_EXAMPLE
661
- drop_join_table :products, :categories
662
- #+END_EXAMPLE
663
- ***** 修改表名 =rename_table=
664
- #+BEGIN_EXAMPLE
665
- rename_table :post, :posts
979
+ excel = 'path/to/excel.xlsx'.parse
980
+ csv = 'path/to/csv.csv'.parse
981
+ json = 'path/to/json.json'.parse
666
982
  #+END_EXAMPLE
667
983
 
668
- ***** =print_tables=
669
-
670
- Arql 提供了一个 =print_tables= 方法,可以将当前数据库中的所有表的信息,导出为:
671
-
672
- + markdown 表格格式: ~print_tables(:md)~
673
- + org-mode 表格格式: ~print_tables(:org)~
674
- + create table SQL: ~print_tables(:sql)~
675
-
676
- **** 模型类类方法扩展
984
+ **** =ID=
677
985
 
678
- Pry 内建了 =show-source= (别名 =$= ) =show-doc= (别名 =?= )命令,可以查看方法的源码和文档。可以通过 =show-doc= 查看方法的文档。例如:
986
+ Arql 提供了一个 =ID= 类,用来生成雪花算法 IDUUID。
679
987
 
680
988
  #+BEGIN_EXAMPLE
681
- ARQL ? Student.add_column
989
+ id = ID.long # 生成一个雪花算法 ID
990
+ id = ID.uuid # 生成一个 UUID
682
991
  #+END_EXAMPLE
992
+
993
+ *** $C 全局变量
683
994
 
684
- ***** 添加字段 =add_column=
685
- #+BEGIN_EXAMPLE
686
- Student.add_column :note, :text, comment: '备注'
687
- #+END_EXAMPLE
995
+ Arql =ActiveRecord::Base.connection= 对象赋值给全局可用的 =$C= 全局变量,它代表当前的数据库连接。
996
+
997
+ 上文中的 =q= 方法实际上是 =$C.exec_query= 方法, =$C= 对象的其他方法也很有用:
998
+
999
+ **** 创建表
1000
+ #+begin_example
1001
+ ARQL ❯ $C.create_table :post, id: false, primary_key: :id do |t|
1002
+ ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
1003
+ ARQL ❯ t.column :name, :string, comment: '名称'
1004
+ ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
1005
+ ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
1006
+ ARQL ❯ end
1007
+ #+end_example
1008
+
1009
+ =create_table= 同样也被加入到 =Kernel= 下面,所以也可以直接调用 =create_table= 方法:
1010
+
1011
+ #+begin_example
1012
+ ARQL ❯ create_table :post, id: false, primary_key: :id do |t|
1013
+ ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
1014
+ ARQL ❯ t.column :name, :string, comment: '名称'
1015
+ ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
1016
+ ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
1017
+ ARQL ❯ end
1018
+ #+end_example
1019
+
1020
+ **** 添加字段
688
1021
 
689
- ***** 修改字段 =change_column=
690
- #+BEGIN_EXAMPLE
691
- Student.change_column :note, :string, comment: '备注'
692
- #+END_EXAMPLE
1022
+ #+begin_example
1023
+ $C.add_column :post, :note, :string, comment: '备注'
1024
+ #+end_example
693
1025
 
694
- ***** 删除字段 =remove_column=
695
- #+BEGIN_EXAMPLE
696
- Student.remove_column :note
697
- #+END_EXAMPLE
1026
+ =add_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =add_column= 方法:
698
1027
 
699
- ***** 添加索引 =add_index=
700
- #+BEGIN_EXAMPLE
701
- Student.add_index :name
702
- Student.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
703
- #+END_EXAMPLE
1028
+ #+begin_example
1029
+ Post.add_column :note, :string, comment: '备注'
1030
+ #+end_example
704
1031
 
705
- ***** 修改字段注释 =change_column_comment=
706
- #+BEGIN_EXAMPLE
707
- Student.change_column_comment :note, '备注'
708
- #+END_EXAMPLE
1032
+ **** 修改字段
1033
+
1034
+ #+begin_example
1035
+ $C.change_column :post, :note, :text, comment: '备注'
1036
+ #+end_example
709
1037
 
710
- ***** 修改字段默认值 =change_column_default=
711
- #+BEGIN_EXAMPLE
712
- Student.change_column_default :note, '默认值'
713
- #+END_EXAMPLE
1038
+ =change_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =change_column= 方法:
1039
+
1040
+ #+begin_example
1041
+ Post.change_column :note, :text, comment: '备注'
1042
+ #+end_example
1043
+
1044
+ **** 删除字段
714
1045
 
715
- ***** 修改字段名称 =rename_column=
716
- #+BEGIN_EXAMPLE
717
- Student.rename_column :note, :remark
718
- #+END_EXAMPLE
1046
+ #+begin_example
1047
+ $C.remove_column :post, :note
1048
+ #+end_example
719
1049
 
720
- ***** 修改表名 =rename_table=
721
- #+BEGIN_EXAMPLE
722
- Student.rename_table :seitou
723
- #+END_EXAMPLE
1050
+ =remove_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =remove_column= 方法:
724
1051
 
725
- ***** 修改表注释 =change_table_comment=
726
- #+BEGIN_EXAMPLE
727
- Student.change_table_comment from: '', to: '学生表'
728
- #+END_EXAMPLE
1052
+ #+begin_example
1053
+ Post.remove_column :note
1054
+ #+end_example
729
1055
 
730
- ***** 删除表 =drop_table=
731
- #+BEGIN_EXAMPLE
732
- Student.drop_table
733
- #+END_EXAMPLE
1056
+ **** 删除表
1057
+
1058
+ #+begin_example
1059
+ $C.drop_table :post
1060
+ #+end_example
734
1061
 
735
- ***** 删除索引 =remove_index=
736
- #+BEGIN_EXAMPLE
737
- Student.remove_index :age
738
- Student.remove_index name: 'by_branch_party'
739
- #+END_EXAMPLE
1062
+ =drop_table= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =drop_table= 方法:
1063
+
1064
+ #+begin_example
1065
+ Post.drop_table
1066
+ #+end_example
1067
+
1068
+ **** 添加索引
740
1069
 
741
- ***** 查询表注释 =table_comment=
742
- #+BEGIN_EXAMPLE
743
- Student.table_comment
744
- #+END_EXAMPLE
1070
+ #+begin_example
1071
+ ARQL ❯ $C.add_index :post, :name
1072
+ ARQL ❯ $C.add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party')
1073
+ #+end_example
745
1074
 
746
- ***** 列出表的索引 =indexes=
747
- #+BEGIN_EXAMPLE
748
- Student.indexes
749
- #+END_EXAMPLE
1075
+ =add_index= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =add_index= 方法:
1076
+
1077
+ #+begin_example
1078
+ Post.add_index :name
1079
+ Post.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
1080
+ #+end_example
750
1081
 
751
- **** 读写 Excel 和 CSV 文件
1082
+ *** 读写 Excel 和 CSV 文件
752
1083
 
753
- Arql 集成了 =roo= 和 =caxlsx= 两个 Excel 库,提供了用于解析和生成 Excel 文件的方法。同时,Arql 也提供了用于读写 CSV 文件的方法。
1084
+ Arql 集成了 =roo= 和 =caxlsx= 两个 Excel 库,提供了用于解析和生成 Excel 文件的方法。同时,Arql 也提供了用于读写 CSV 文件的方法。
754
1085
 
755
- ***** 解析 Excel
1086
+ **** 解析 Excel
756
1087
 
757
- Arql 为 =Kernel= 模块添加了 =parse_excel= 方法,可以用来解析 Excel 文件。例如:
1088
+ Arql 为 =Kernel= 模块添加了 =parse_excel= 方法,可以用来解析 Excel 文件。例如:
758
1089
 
759
- #+BEGIN_EXAMPLE
760
- ARQL ❯ parse_excel 'path/to/excel.xlsx'
761
- #+END_EXAMPLE
1090
+ #+BEGIN_EXAMPLE
1091
+ ARQL ❯ parse_excel 'path/to/excel.xlsx'
1092
+ #+END_EXAMPLE
762
1093
 
763
- 文件路径中可以使用 =~/= 表示用户的主目录,Arql 会自动展开。
1094
+ 文件路径中可以使用 =~/= 表示用户的主目录,Arql 会自动展开。
764
1095
 
765
1096
 
766
- 也可以在一个表示文件路径的 =String= 对象上调用 =parse_excel= 方法:
1097
+ 也可以在一个表示文件路径的 =String= 对象上调用 =parse_excel= 方法:
767
1098
 
768
- #+BEGIN_EXAMPLE
769
- ARQL ❯ 'path/to/excel.xlsx'.parse_excel
770
- #+END_EXAMPLE
1099
+ #+BEGIN_EXAMPLE
1100
+ ARQL ❯ 'path/to/excel.xlsx'.parse_excel
1101
+ #+END_EXAMPLE
771
1102
 
772
- =parse_excel= 方法会返回一个 =Hash= 对象,Key 为 Sheet 名称,Value 为 Sheet 的数据,Value 是一个二维数组。例如:
1103
+ =parse_excel= 方法会返回一个 =Hash= 对象,Key 为 Sheet 名称,Value 为 Sheet 的数据,Value 是一个二维数组。例如:
773
1104
 
774
- #+BEGIN_EXAMPLE
775
- {
776
- 'Sheet1' => [
777
- ['A1', 'B1', 'C1'],
778
- ['A2', 'B2', 'C2'],
779
- ['A3', 'B3', 'C3']
780
- ],
781
- 'Sheet2' => [
782
- ['A1', 'B1', 'C1'],
783
- ['A2', 'B2', 'C2'],
784
- ['A3', 'B3', 'C3']
785
- ]
786
- }
787
- #+END_EXAMPLE
1105
+ #+BEGIN_EXAMPLE
1106
+ {
1107
+ 'Sheet1' => [
1108
+ ['A1', 'B1', 'C1'],
1109
+ ['A2', 'B2', 'C2'],
1110
+ ['A3', 'B3', 'C3']
1111
+ ],
1112
+ 'Sheet2' => [
1113
+ ['A1', 'B1', 'C1'],
1114
+ ['A2', 'B2', 'C2'],
1115
+ ['A3', 'B3', 'C3']
1116
+ ]
1117
+ }
1118
+ #+END_EXAMPLE
788
1119
 
789
- ***** 生成 Excel
1120
+ **** 生成 Excel
790
1121
 
791
- Arql 为 =Hash= / =Array= / =ActiveRecord::Relation= / =ActiveRecord::Base= 对象添加了 =write_excel= 方法,可以用来
792
- 生成 Excel 文件:
1122
+ Arql 为 =Hash= / =Array= / =ActiveRecord::Relation= / =ActiveRecord::Base= 对象添加了 =write_excel= 方法,可以用来
1123
+ 生成 Excel 文件:
793
1124
 
794
- ****** 从 =Hash= 对象生成 Excel
1125
+ ***** 从 =Hash= 对象生成 Excel
795
1126
 
796
- #+BEGIN_EXAMPLE
797
- ARQL ❯ obj.write_excel 'path/to/excel.xlsx'
798
- #+END_EXAMPLE
1127
+ #+BEGIN_EXAMPLE
1128
+ ARQL ❯ obj.write_excel 'path/to/excel.xlsx'
1129
+ #+END_EXAMPLE
799
1130
 
800
- =Hash#write_excel= 要求 Hash 对象 Key 是 Sheet 名称,Value 是 Sheet 的数据,Value 的类型可以是:
1131
+ =Hash#write_excel= 要求 Hash 对象 Key 是 Sheet 名称,Value 是 Sheet 的数据,Value 的类型可以是:
801
1132
 
802
- + 一个数组,数组的元素可以是:
803
- + 一个数组,表示一行数据
804
- + 一个 Hash 对象,表示一行数据,Key 是列名,Value 是列值
805
- + 一个 ActiveRecord::Base 对象,表示一行数据
806
- + 一个 Hash 对象,一共包含两个键值对:
807
- + =:fields=, 一个数组,表示列名
808
- + =:data=, 一个二维数组,表示数据
1133
+ + 一个数组,数组的元素可以是:
1134
+ + 一个数组,表示一行数据
1135
+ + 一个 Hash 对象,表示一行数据,Key 是列名,Value 是列值
1136
+ + 一个 ActiveRecord::Base 对象,表示一行数据
1137
+ + 一个 Hash 对象,一共包含两个键值对:
1138
+ + =:fields=, 一个数组,表示列名
1139
+ + =:data=, 一个二维数组,表示数据
809
1140
 
810
- ****** 从 =Array= 对象生成 Excel
1141
+ ***** 从 =Array= 对象生成 Excel
811
1142
 
812
- #+BEGIN_EXAMPLE
813
- ARQL ❯ obj.write_excel 'path/to/excel.xlsx', :name, :age, :gender, sheet_name: '订单数据'
814
- #+END_EXAMPLE
1143
+ #+BEGIN_EXAMPLE
1144
+ ARQL ❯ obj.write_excel 'path/to/excel.xlsx', :name, :age, :gender, sheet_name: '订单数据'
1145
+ #+END_EXAMPLE
815
1146
 
816
- 其中:
1147
+ 其中:
817
1148
 
818
- + =:name, :age, :gender= 这几个参数是列名,如果不指定,会根据数组的第一个元素来确定列名:
819
- - 如果元素是 =ActiveRecord::Base= 对象,会使用对象的全部属性名(即数据库字段列表)作为列名
820
- - 如果元素是 =Hash= 对象,会使用 =Hash= 的 全部 Key 作为列名
821
- + =sheet_name= 指定 Sheet 名称,如果不指定,会使用默认的 Sheet 名称 =Sheet1=
1149
+ + =:name, :age, :gender= 这几个参数是列名,如果不指定,会根据数组的第一个元素来确定列名:
1150
+ - 如果元素是 =ActiveRecord::Base= 对象,会使用对象的全部属性名(即数据库字段列表)作为列名
1151
+ - 如果元素是 =Hash= 对象,会使用 =Hash= 的 全部 Key 作为列名
1152
+ + =sheet_name= 指定 Sheet 名称,如果不指定,会使用默认的 Sheet 名称 =Sheet1=
822
1153
 
823
- =Array= 对象的每一个元素表示一行数据, =Array#write_excel= 要求 Array 对象每个元素:
1154
+ =Array= 对象的每一个元素表示一行数据, =Array#write_excel= 要求 Array 对象每个元素:
824
1155
 
825
- + 一个 =ActiveRecord::Base= 对象
826
- + 一个 =Hash= 对象,表示一行数据,Key 是列名,Value 是列值
827
- + 一个数组,表示一行数据
1156
+ + 一个 =ActiveRecord::Base= 对象
1157
+ + 一个 =Hash= 对象,表示一行数据,Key 是列名,Value 是列值
1158
+ + 一个数组,表示一行数据
828
1159
 
829
- ****** 从 =ActiveRecord::Base= 对象生成 Excel
1160
+ ***** 从 =ActiveRecord::Base= 对象生成 Excel
830
1161
 
831
- #+BEGIN_EXAMPLE
832
- ARQL ❯ Student.find(123).write_excel 'path/to/excel.xlsx', sheet_name: '学生数据'
833
- #+END_EXAMPLE
1162
+ #+BEGIN_EXAMPLE
1163
+ ARQL ❯ Student.find(123).write_excel 'path/to/excel.xlsx', sheet_name: '学生数据'
1164
+ #+END_EXAMPLE
834
1165
 
835
- =ActiveRecord::Base= 的 =write_excel= 对象实际上就是把这个 =ActiveRecord::Base= 对象包装成一个只有一个元素的 =Array= 对
836
- 象,然后调用 =Array= 的 =write_excel= 方法。
1166
+ =ActiveRecord::Base= 的 =write_excel= 对象实际上就是把这个 =ActiveRecord::Base= 对象包装成一个只有一个元素的 =Array= 对
1167
+ 象,然后调用 =Array= 的 =write_excel= 方法。
837
1168
 
838
- ****** 从 =ActiveRecord::Relation= 对象生成 Excel
1169
+ ***** 从 =ActiveRecord::Relation= 对象生成 Excel
839
1170
 
840
- #+BEGIN_EXAMPLE
841
- ARQL ❯ Student.where(gender: 'M').write_excel 'path/to/excel.xlsx', sheet_name: '男学生'
842
- #+END_EXAMPLE
1171
+ #+BEGIN_EXAMPLE
1172
+ ARQL ❯ Student.where(gender: 'M').write_excel 'path/to/excel.xlsx', sheet_name: '男学生'
1173
+ #+END_EXAMPLE
843
1174
 
844
- =ActiveRecord::Relation= 的 =write_excel= 对象实际上就是把这个 =ActiveRecord::Relation= 对象转换成一个 =Array= 对象,然
845
- 后调用 =Array= 的 =write_excel= 方法。
1175
+ =ActiveRecord::Relation= 的 =write_excel= 对象实际上就是把这个 =ActiveRecord::Relation= 对象转换成一个 =Array= 对象,然
1176
+ 后调用 =Array= 的 =write_excel= 方法。
846
1177
 
847
- ***** 解析 CSV
1178
+ **** 解析 CSV
848
1179
 
849
- Arql 提供了 =parse_csv= 方法,可以用来解析 CSV 文件:
1180
+ Arql 提供了 =parse_csv= 方法,可以用来解析 CSV 文件:
850
1181
 
851
- #+BEGIN_EXAMPLE
852
- ARQL ❯ parse_csv 'path/to/csv.csv'
853
- #+END_EXAMPLE
1182
+ #+BEGIN_EXAMPLE
1183
+ ARQL ❯ parse_csv 'path/to/csv.csv'
1184
+ #+END_EXAMPLE
854
1185
 
855
- =parse_csv= 方法返回一个标准库中的 CSV 对象。
1186
+ =parse_csv= 方法返回一个标准库中的 CSV 对象。
856
1187
 
857
- =parse_csv= 可以有以下选项参数:
1188
+ =parse_csv= 可以有以下选项参数:
858
1189
 
859
- - =encoding=, 指定 CSV 文件的编码,默认是 =UTF-16= (with BOM)
860
- - =headers=, 指定是否包含表头,默认是 =false=
861
- - =col_sep=, 指定列分隔符,默认是 =\t=
862
- - =row_sep=, 指定行分隔符,默认是 =\r\n=
1190
+ - =encoding=, 指定 CSV 文件的编码,默认是 =UTF-16= (with BOM)
1191
+ - =headers=, 指定是否包含表头,默认是 =false=
1192
+ - =col_sep=, 指定列分隔符,默认是 =\t=
1193
+ - =row_sep=, 指定行分隔符,默认是 =\r\n=
863
1194
 
864
- (以上默认值实际就是 Microsoft Office Excel 保存 CSV 文件时默认使用的配置)
1195
+ (以上默认值实际就是 Microsoft Office Excel 保存 CSV 文件时默认使用的配置)
865
1196
 
866
- 也可以在一个表示文件路径的 =String= 对象上调用 =parse_csv= 方法:
1197
+ 也可以在一个表示文件路径的 =String= 对象上调用 =parse_csv= 方法:
867
1198
 
868
- #+BEGIN_EXAMPLE
869
- ARQL ❯ 'path/to/csv.csv'.parse_csv
870
- #+END_EXAMPLE
1199
+ #+BEGIN_EXAMPLE
1200
+ ARQL ❯ 'path/to/csv.csv'.parse_csv
1201
+ #+END_EXAMPLE
871
1202
 
872
- ***** 生成 CSV
873
- Arql 为 =Array= / =ActiveRecord::Relation= / =ActiveRecord::Base= 对象添加了 =write_csv= 方法,可以用来生成 CSV 文件:
1203
+ **** 生成 CSV
1204
+ Arql 为 =Array= / =ActiveRecord::Relation= / =ActiveRecord::Base= 对象添加了 =write_csv= 方法,可以用来生成 CSV 文件:
874
1205
 
875
- ****** 从 =Array= 对象生成 CSV
1206
+ ***** 从 =Array= 对象生成 CSV
876
1207
 
877
- #+BEGIN_EXAMPLE
878
- ARQL ❯ obj.write_csv 'path/to/csv.csv', :name, :age, :gender, sheet_name: '订单数据'
879
- #+END_EXAMPLE
1208
+ #+BEGIN_EXAMPLE
1209
+ ARQL ❯ obj.write_csv 'path/to/csv.csv', :name, :age, :gender, sheet_name: '订单数据'
1210
+ #+END_EXAMPLE
880
1211
 
881
- 用法和 =Array= 对象的 =write_excel= 方法类似。
1212
+ 用法和 =Array= 对象的 =write_excel= 方法类似。
882
1213
 
883
1214
 
884
- ****** 从 =ActiveRecord::Base= 对象生成 CSV
1215
+ ***** 从 =ActiveRecord::Base= 对象生成 CSV
885
1216
 
886
- #+BEGIN_EXAMPLE
887
- ARQL ❯ Student.find(123).write_csv 'path/to/csv.csv', sheet_name: '学生数据'
888
- #+END_EXAMPLE
1217
+ #+BEGIN_EXAMPLE
1218
+ ARQL ❯ Student.find(123).write_csv 'path/to/csv.csv', sheet_name: '学生数据'
1219
+ #+END_EXAMPLE
889
1220
 
890
- 用法和 =ActiveRecord::Base= 对象的 =write_excel= 方法类似。
1221
+ 用法和 =ActiveRecord::Base= 对象的 =write_excel= 方法类似。
891
1222
 
892
- ****** 从 =ActiveRecord::Relation= 对象生成 CSV
1223
+ ***** 从 =ActiveRecord::Relation= 对象生成 CSV
893
1224
 
894
- #+BEGIN_EXAMPLE
895
- ARQL ❯ Student.where(gender: 'M').write_csv 'path/to/csv.csv', sheet_name: '男学生'
896
- #+END_EXAMPLE
1225
+ #+BEGIN_EXAMPLE
1226
+ ARQL ❯ Student.where(gender: 'M').write_csv 'path/to/csv.csv', sheet_name: '男学生'
1227
+ #+END_EXAMPLE
897
1228
 
898
- 用法和 =ActiveRecord::Relation= 对象的 =write_excel= 方法类似。
1229
+ 用法和 =ActiveRecord::Relation= 对象的 =write_excel= 方法类似。
899
1230
 
900
- **** dump 数据
1231
+ *** dump 数据
901
1232
 
902
- 注意: 仅支持 MySQL 数据库
1233
+ 注意: 仅支持 MySQL 数据库
903
1234
 
904
- Arql 为 =Array= / =ActiveRecord::Base= / =ActiveRecord::Relation= 等对象添加了 =dump= 方法,可以用来导出数据到 SQL 文件:
1235
+ Arql 为 =Array= / =ActiveRecord::Base= / =ActiveRecord::Relation= 等对象添加了 =dump= 方法,可以用来导出数据到 SQL 文件:
905
1236
 
906
1237
 
907
- ***** 从 Array 对象导出数据
1238
+ **** 从 Array 对象导出数据
908
1239
 
909
- #+BEGIN_EXAMPLE
910
- ARQL ❯ obj.dump 'path/to/dump.sql', batch_size: 5000
911
- #+END_EXAMPLE
1240
+ #+BEGIN_EXAMPLE
1241
+ ARQL ❯ obj.dump 'path/to/dump.sql', batch_size: 5000
1242
+ #+END_EXAMPLE
912
1243
 
913
- =Array= 对象的每一个元素必须是一个 =ActiveRecord::Base= 对象
1244
+ =Array= 对象的每一个元素必须是一个 =ActiveRecord::Base= 对象
914
1245
 
915
- =batch_size= 参数指定每个批次查询出的数据,默认值为 500
1246
+ =batch_size= 参数指定每个批次查询出的数据,默认值为 500
916
1247
 
917
- ***** 从 ActiveRecord::Base 对象导出数据
1248
+ **** 从 ActiveRecord::Base 对象导出数据
918
1249
 
919
- #+BEGIN_EXAMPLE
920
- ARQL ❯ Student.find(123).dump 'path/to/dump.sql', batch_size: 5000
921
- #+END_EXAMPLE
1250
+ #+BEGIN_EXAMPLE
1251
+ ARQL ❯ Student.find(123).dump 'path/to/dump.sql', batch_size: 5000
1252
+ #+END_EXAMPLE
922
1253
 
923
- =ActiveRecord::Base= 对象的 =dump= 方法实际上就是把这个 =ActiveRecord::Base= 对象包装成一个只有一个元素的 =Array= 对象,然后调用 =Array= 的 =dump= 方法。
1254
+ =ActiveRecord::Base= 对象的 =dump= 方法实际上就是把这个 =ActiveRecord::Base= 对象包装成一个只有一个元素的 =Array= 对象,然后调用 =Array= 的 =dump= 方法。
924
1255
 
925
- ***** 从 ActiveRecord::Relation 对象导出数据
1256
+ **** 从 ActiveRecord::Relation 对象导出数据
926
1257
 
927
- #+BEGIN_EXAMPLE
928
- ARQL ❯ Student.where(gender: 'M').dump 'path/to/dump.sql', batch_size: 5000
929
- #+END_EXAMPLE
1258
+ #+BEGIN_EXAMPLE
1259
+ ARQL ❯ Student.where(gender: 'M').dump 'path/to/dump.sql', batch_size: 5000
1260
+ #+END_EXAMPLE
930
1261
 
931
- =ActiveRecord::Relation= 的 =dump= 对象实际上就是把这个 =ActiveRecord::Relation= 对象转换成一个 =Array= 对象,然后调用 =Array= 的 =dump= 方法。
1262
+ =ActiveRecord::Relation= 的 =dump= 对象实际上就是把这个 =ActiveRecord::Relation= 对象转换成一个 =Array= 对象,然后调用 =Array= 的 =dump= 方法。
932
1263
 
933
-
934
- ***** 调用 ActiveRecord::Base 的 dump 类方法
1264
+ **** 调用 ActiveRecord::Base 的 dump 类方法
935
1265
 
936
- #+BEGIN_EXAMPLE
937
- ARQL ❯ Student.dump 'path/to/dump.sql', no_create_table: false
938
- #+END_EXAMPLE
1266
+ #+BEGIN_EXAMPLE
1267
+ ARQL ❯ Student.dump 'path/to/dump.sql', no_create_table: false
1268
+ #+END_EXAMPLE
939
1269
 
940
- 这个方法会通过 =mysqldump= 命令 把 =Student= 表中的所有数据导出到 SQL 文件中。
1270
+ 这个方法会通过 =mysqldump= 命令 把 =Student= 表中的所有数据导出到 SQL 文件中。
941
1271
 
942
- =no_create_table= 参数指定是否在 SQL 文件中包含创建表的语句,默认值为 =false= 。
1272
+ =no_create_table= 参数指定是否在 SQL 文件中包含创建表的语句,默认值为 =false= 。
943
1273
 
944
1274
 
945
-
946
- ***** 在全局连接对象 =$C= 上调用 dump 方法
1275
+ **** 在全局连接对象 =$C= 上调用 dump 方法
947
1276
 
948
- #+BEGIN_EXAMPLE
949
- ARQL ❯ $C.dump 'path/to/dump.sql', no_create_db: false
950
- #+END_EXAMPLE
1277
+ #+BEGIN_EXAMPLE
1278
+ ARQL ❯ $C.dump 'path/to/dump.sql', no_create_db: false
1279
+ #+END_EXAMPLE
951
1280
 
952
- 这个方法会通过 mysqldump 命令把当前数据库中的所有表的数据导出到 SQL 文件中。
1281
+ 这个方法会通过 mysqldump 命令把当前数据库中的所有表的数据导出到 SQL 文件中。
953
1282
 
954
- =no_create_db= 参数指定是否在 SQL 文件中包含创建数据库的语句,默认值为 =false= 。
1283
+ =no_create_db= 参数指定是否在 SQL 文件中包含创建数据库的语句,默认值为 =false= 。
955
1284
 
956
-
957
- **** Plot
958
-
959
- Arql 集成了 Ruby 的 =youplot= 库,为 =Array= 添加了一些可以用来绘制图表的方法:
960
-
961
- + =barplot=
962
- + =countplot=
963
- + =histo=
964
- + =lineplot=
965
- + =lineplots=
966
- + =scatter=
967
- + =density=
968
- + =boxplot=
1285
+ *** Plot
1286
+
1287
+ Arql 集成了 Ruby 的 =youplot= 库,为 =Array= 添加了一些可以用来绘制图表的方法:
1288
+
1289
+ + =barplot=
1290
+ + =countplot=
1291
+ + =histo=
1292
+ + =lineplot=
1293
+ + =lineplots=
1294
+ + =scatter=
1295
+ + =density=
1296
+ + =boxplot=
969
1297
 
970
- 示例:
1298
+ 示例:
971
1299
 
972
- 数量统计图:
1300
+ 数量统计图:
973
1301
 
974
- #+BEGIN_EXAMPLE
975
- ARQL@demo247(main) [44] ❯ Student.pluck(:gender)
976
- => ["M", "M", "M", "M", "M", "M", "M", "F", "M", "F", "M", "M", "M", "M", "M"]
977
- ARQL@demo247(main) [45] ❯ Student.pluck(:gender).countplot
978
- ┌ ┐
979
- M ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 13.0
980
- F ┤■■■■■ 2.0
981
- └ ┘
982
- #+END_EXAMPLE
1302
+ #+BEGIN_EXAMPLE
1303
+ ARQL@demo247(main) [44] ❯ Student.pluck(:gender)
1304
+ => ["M", "M", "M", "M", "M", "M", "M", "F", "M", "F", "M", "M", "M", "M", "M"]
1305
+ ARQL@demo247(main) [45] ❯ Student.pluck(:gender).countplot
1306
+ ┌ ┐
1307
+ M ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 13.0
1308
+ F ┤■■■■■ 2.0
1309
+ └ ┘
1310
+ #+END_EXAMPLE
983
1311
 
984
- 分布图:
1312
+ 分布图:
985
1313
 
986
- #+BEGIN_EXAMPLE
987
- ARQL@jicai.dev(main) [18] ❯ Order.last(20).pluck(:order_sum)
988
- => [0.21876e5, 0.336571e5, 0.1934e5, 0.966239e4, 0.38748e3, 0.31092e4, 0.483e5, 0.445121e5, 0.1305e4, 0.2296e6, 0.943e5, 0.352e4, 0.3756e5, 0.323781e5, 0.7937622e5, 0.982e4, 0.338393e5, 0.316597e5, 0.213678e5, 0.336845e5]
989
- ARQL@jicai.dev(main) [19] ❯ Order.last(20).pluck(:order_sum).histo
990
- ┌ ┐
991
- [ 0.0, 50000.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 17
992
- [ 50000.0, 100000.0) ┤▇▇▇▇ 2
993
- [100000.0, 150000.0) ┤ 0
994
- [150000.0, 200000.0) ┤ 0
995
- [200000.0, 250000.0) ┤▇▇ 1
996
- └ ┘
997
- Frequency
1314
+ #+BEGIN_EXAMPLE
1315
+ ARQL@jicai.dev(main) [18] ❯ Order.last(20).pluck(:order_sum)
1316
+ => [0.21876e5, 0.336571e5, 0.1934e5, 0.966239e4, 0.38748e3, 0.31092e4, 0.483e5, 0.445121e5, 0.1305e4, 0.2296e6, 0.943e5, 0.352e4, 0.3756e5, 0.323781e5, 0.7937622e5, 0.982e4, 0.338393e5, 0.316597e5, 0.213678e5, 0.336845e5]
1317
+ ARQL@jicai.dev(main) [19] ❯ Order.last(20).pluck(:order_sum).histo
1318
+ ┌ ┐
1319
+ [ 0.0, 50000.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 17
1320
+ [ 50000.0, 100000.0) ┤▇▇▇▇ 2
1321
+ [100000.0, 150000.0) ┤ 0
1322
+ [150000.0, 200000.0) ┤ 0
1323
+ [200000.0, 250000.0) ┤▇▇ 1
1324
+ └ ┘
1325
+ Frequency
998
1326
 
999
- #+END_EXAMPLE
1000
-
1001
- **** =String=
1327
+ #+END_EXAMPLE
1002
1328
 
1003
- ***** =Srting#p=
1329
+ *** Ransack
1004
1330
 
1005
- =p= 方法的定义如下:
1006
-
1007
- #+begin_example
1008
- class String
1009
- def p
1010
- puts self
1011
- end
1012
- end
1013
- #+end_example
1014
-
1015
- =​"hello".p= 等价于 =puts "hello"​= 。
1016
-
1017
- ***** =String#parse=
1018
-
1019
- 对于一个表示文件路径的字符串,可以调用 =parse= 方法通过文件路径中的后缀名来分别对 Excel、CSV、JSON 文件进行解析。
1020
-
1021
- #+BEGIN_EXAMPLE
1022
- excel = 'path/to/excel.xlsx'.parse
1023
- csv = 'path/to/csv.csv'.parse
1024
- json = 'path/to/json.json'.parse
1025
- #+END_EXAMPLE
1026
-
1027
- **** =ID=
1028
-
1029
- Arql 提供了一个 =ID= 类,用来生成雪花算法 ID 和 UUID。
1331
+ Arql 集成了 =Ransack=:
1030
1332
 
1031
1333
  #+BEGIN_EXAMPLE
1032
- id = ID.long # 生成一个雪花算法 ID
1033
- id = ID.uuid # 生成一个 UUID
1334
+ Student.ransack(name_cont: 'Tom').result # 模糊查询名字中包含 'Tom' 的学生
1335
+ Student.ransack(name_start: 'Tom').result # 模糊查询名字以 'Tom' 开头的学生
1034
1336
  #+END_EXAMPLE
1035
-
1036
- **** Ransack
1037
-
1038
- Arql 集成了 =Ransack=:
1039
-
1040
- #+BEGIN_EXAMPLE
1041
- Student.ransack(name_cont: 'Tom').result # 模糊查询名字中包含 'Tom' 的学生
1042
- Student.ransack(name_start: 'Tom').result # 模糊查询名字以 'Tom' 开头的学生
1043
- #+END_EXAMPLE
1044
1337
 
1045
- *** Emacs Org Babel 集成
1338
+ ** Emacs Org Babel 集成
1046
1339
 
1047
- 这里有一个 [[https://github.com/lululau/spacemacs-layers/blob/master/ob-arql/local/ob-arql/ob-arql.el][ob-arql]] 用于集成 Emacs org babel。
1340
+ 这里有一个 [[https://github.com/lululau/spacemacs-layers/blob/master/ob-arql/local/ob-arql/ob-arql.el][ob-arql]] 用于集成 Emacs org babel。
1048
1341
 
1049
1342
  ** Guides and Tips
1050
1343
  *** [[./define-associations-zh_CN.org][在 Initializer 文件中定义关联关系]]
@@ -1062,19 +1355,9 @@
1062
1355
  #+BEGIN_EXAMPLE
1063
1356
  arql -d db/development.sqlite3
1064
1357
  #+END_EXAMPLE
1065
-
1066
- *** 根据名称或注释查找字段
1067
-
1068
- 我们在熟悉一个项目的时候,经常会遇到这样的情况:我们知道某个字段的名称或注释,但是不知道它对应的表名和字段名。这时候我们可以使用如下方法来查找:
1069
-
1070
- #+BEGIN_SRC ruby
1071
- puts model_classes.flat_map { |m| m.columns.select {|c| c.name =~ /amount/ || c.comment =~ /金额/ }.map {|c| "Table: #{m.table_name}, Column: #{c.name} (#{c.comment})"} }
1072
-
1073
- # 输出:
1074
- # Table: order, Column: entry_amount (订单金额)
1075
- # Table: sub_order, Column: entry_price (金额)
1076
- #+END_SRC
1077
-
1358
+ *** [[./ruby-guides-for-java-developer-zh_CN.org][给 Java 开发者的 Ruby 入门简明教程]]
1359
+ *** [[./simple-pry-guides-zh_CN.org][简明 Pry 使用指南]]
1360
+ *** [[./simple-active-record-guide-zh_CN.org][简明 ActiveRecord 使用指南]]
1078
1361
  ** 开发
1079
1362
 
1080
1363
  检出代码后,运行 =bin/setup= 安装依赖。你也可以运行 =bin/console= 进入交互式控制台。