card 1.103.2 → 1.104.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/environments/development.rb +4 -2
  4. data/config/environments/production.rb +9 -9
  5. data/config/environments/test.rb +1 -1
  6. data/config/initializers/01_core_extensions/array.rb +4 -1
  7. data/config/initializers/01_core_extensions/object.rb +1 -1
  8. data/config/initializers/02_patches/active_record.rb +16 -17
  9. data/config/locales/de.yml +8 -564
  10. data/config/locales/es.yml +2 -3
  11. data/db/migrate/20110511221913_require_earlier_migrations.rb +1 -1
  12. data/db/migrate/20120105203350_require_1_8_migrations.rb +1 -1
  13. data/db/migrate/20121111025347_require_1_10_migrations.rb +1 -1
  14. data/db/migrate/20211128040849_virtuals_updated_at.rb +11 -0
  15. data/db/migrate_core_cards/20130411191151_renaming_for_menu.rb +0 -1
  16. data/db/migrate_core_cards/20140317035504_account_requests_to_signups.rb +0 -2
  17. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +0 -2
  18. data/db/migrate_core_cards/20190417142612_reorganize_scripts_2.rb +1 -3
  19. data/db/migrate_core_cards/20190502130029_add_shark_and_help_desk_role.rb +1 -2
  20. data/db/migrate_core_cards/20190710090209_homepage_tweaks.rb +3 -7
  21. data/db/migrate_core_cards/20190823220018_cleanup_for_decko_1_0.rb +2 -4
  22. data/db/migrate_core_cards/20190902193208_input_type.rb +3 -8
  23. data/db/migrate_core_cards/20190904174403_token_upgrade.rb +1 -1
  24. data/db/migrate_core_cards/data/1.12_stylesheets/traditional.scss +1 -2
  25. data/db/schema.rb +19 -16
  26. data/db/seed/new/card_actions.yml +2615 -3383
  27. data/db/seed/new/card_acts.yml +3 -3
  28. data/db/seed/new/card_references.yml +1588 -1707
  29. data/db/seed/new/cards.yml +5450 -8416
  30. data/db/seed/new/schema_migrations.yml +2 -0
  31. data/db/seed/new/schema_migrations_core_cards.yml +8 -0
  32. data/db/seed/test/fixtures/card_actions.yml +4304 -5144
  33. data/db/seed/test/fixtures/card_acts.yml +780 -840
  34. data/db/seed/test/fixtures/card_changes.yml +110 -110
  35. data/db/seed/test/fixtures/card_references.yml +2908 -2992
  36. data/db/seed/test/fixtures/cards.yml +8775 -11955
  37. data/db/seed/test/fixtures/schema_migrations.yml +2 -0
  38. data/db/seed/test/fixtures/schema_migrations_core_cards.yml +8 -0
  39. data/db/test_seed.rb +2 -5
  40. data/db/version.txt +1 -1
  41. data/db/version_core_cards.txt +1 -1
  42. data/lib/card/auth/current.rb +1 -1
  43. data/lib/card/auth/permissions.rb +37 -35
  44. data/lib/card/content/all.rb +3 -3
  45. data/lib/card/content/chunk.rb +1 -1
  46. data/lib/card/content/diff/summary.rb +14 -18
  47. data/lib/card/content.rb +9 -1
  48. data/lib/card/director/act_direction.rb +6 -6
  49. data/lib/card/director/card_methods.rb +0 -1
  50. data/lib/card/director/phases.rb +1 -0
  51. data/lib/card/director/stages.rb +2 -0
  52. data/lib/card/director.rb +1 -0
  53. data/lib/card/fetch/all.rb +3 -3
  54. data/lib/card/fetch/card_class.rb +5 -11
  55. data/lib/card/fetch/results.rb +8 -8
  56. data/lib/card/{tasks/card/file_card_creator → file_card_creator}/abstract_file_card/migration_file.rb +0 -0
  57. data/lib/card/{tasks/card/file_card_creator → file_card_creator}/abstract_file_card/ruby_file.rb +0 -0
  58. data/lib/card/{tasks/card/file_card_creator → file_card_creator}/abstract_file_card/source_file.rb +0 -0
  59. data/lib/card/{tasks/card/file_card_creator → file_card_creator}/abstract_file_card.rb +0 -5
  60. data/lib/card/{tasks/card/file_card_creator → file_card_creator}/haml_card.rb +0 -0
  61. data/lib/card/{tasks/card/file_card_creator → file_card_creator}/output_helper.rb +0 -0
  62. data/lib/card/{tasks/card/file_card_creator → file_card_creator}/script_card.rb +0 -0
  63. data/lib/card/{tasks/card/file_card_creator → file_card_creator}/style_card.rb +0 -0
  64. data/lib/card/{tasks/card/file_card_creator.rb → file_card_creator.rb} +0 -5
  65. data/lib/card/format/content.rb +5 -7
  66. data/lib/card/format/error.rb +2 -2
  67. data/lib/card/format/render.rb +10 -10
  68. data/lib/card/format.rb +3 -8
  69. data/lib/card/lexicon.rb +30 -7
  70. data/lib/card/model/save_helper/save_arguments.rb +2 -2
  71. data/lib/card/model/save_helper.rb +3 -3
  72. data/lib/card/name/all/descendants.rb +9 -7
  73. data/lib/card/name/all/parts.rb +1 -1
  74. data/lib/card/name/all.rb +4 -3
  75. data/lib/card/name/card_class.rb +2 -1
  76. data/lib/card/name/fields_and_traits.rb +6 -30
  77. data/lib/card/name/name_variants.rb +5 -1
  78. data/lib/card/name.rb +6 -14
  79. data/lib/card/query/abstract_query/tie.rb +2 -3
  80. data/lib/card/query/card_query/normalization.rb +1 -1
  81. data/lib/card/query/sql_statement/order.rb +5 -6
  82. data/lib/card/query/value.rb +10 -7
  83. data/lib/card/reference/all.rb +9 -7
  84. data/lib/card/reference.rb +36 -41
  85. data/lib/card/rule/all.rb +3 -3
  86. data/lib/card/set/advanced_api.rb +5 -0
  87. data/lib/card/set/card_methods.rb +13 -0
  88. data/lib/card/set/event/delayed_event.rb +8 -1
  89. data/lib/card/set/event/skip_and_trigger.rb +8 -0
  90. data/lib/card/set/event.rb +1 -0
  91. data/lib/card/set/format/abstract_format/wrapper.rb +1 -1
  92. data/lib/card/set/format/abstract_format.rb +2 -1
  93. data/lib/card/set/format.rb +2 -3
  94. data/lib/card/set/helpers.rb +68 -0
  95. data/lib/card/set/inheritance.rb +1 -1
  96. data/lib/card/set/pattern/all.rb +20 -10
  97. data/lib/card/set/pattern/base.rb +12 -18
  98. data/lib/card/set/pattern/class_methods.rb +13 -13
  99. data/lib/card/set/pattern.rb +46 -24
  100. data/lib/card/set/registrar.rb +8 -2
  101. data/lib/card/set/trait.rb +16 -1
  102. data/lib/card/set/type.rb +3 -0
  103. data/lib/card/set.rb +14 -7
  104. data/lib/card/subcards/add.rb +1 -3
  105. data/lib/card/subcards/all.rb +30 -56
  106. data/lib/card/view/classy.rb +15 -27
  107. data/lib/card/view/options/voo_api.rb +3 -1
  108. data/lib/card/view/options.rb +7 -5
  109. data/lib/card/view/permission.rb +4 -11
  110. data/lib/card/view.rb +1 -0
  111. data/lib/card.rb +9 -11
  112. data/lib/cardio/cli.rb +1 -0
  113. data/lib/cardio/commands/custom.rb +60 -0
  114. data/lib/cardio/commands/rake_command/parser.rb +49 -48
  115. data/lib/cardio/commands/rake_command.rb +17 -15
  116. data/lib/cardio/commands/rspec_command.rb +2 -0
  117. data/lib/cardio/commands.rb +69 -69
  118. data/lib/cardio/generators/deck_helper.rb +0 -4
  119. data/lib/cardio/generators.rb +56 -3
  120. data/lib/cardio/migration/deck.rb +0 -0
  121. data/lib/cardio/migration/deck_structure.rb +2 -0
  122. data/lib/cardio/migration/import/import_data/card_content.rb +1 -1
  123. data/lib/cardio/migration/import.rb +2 -2
  124. data/lib/cardio/migration.rb +26 -2
  125. data/lib/cardio/mod/class_methods.rb +112 -0
  126. data/lib/cardio/mod/dirs.rb +15 -11
  127. data/lib/cardio/mod/eat/edibles.rb +92 -0
  128. data/lib/cardio/mod/eat.rb +81 -0
  129. data/lib/cardio/mod/load_strategy/set_tmp_files.rb +10 -4
  130. data/lib/cardio/mod/load_strategy/tmp_files.rb +1 -1
  131. data/lib/cardio/mod/load_strategy.rb +3 -4
  132. data/lib/cardio/mod/loader/set_loader.rb +13 -13
  133. data/lib/cardio/mod/loader.rb +1 -1
  134. data/lib/cardio/mod/modfile_api.rb +5 -0
  135. data/lib/cardio/mod/poop.rb +135 -0
  136. data/lib/cardio/mod.rb +20 -80
  137. data/lib/cardio/railtie.rb +24 -6
  138. data/lib/cardio/schema.rb +11 -10
  139. data/lib/cardio/version.rb +35 -0
  140. data/lib/cardio.rb +4 -0
  141. data/lib/generators/deck/deck_generator.rb +3 -2
  142. data/lib/generators/deck/templates/Gemfile.erb +1 -5
  143. data/lib/generators/deck/templates/Rakefile.erb +6 -2
  144. data/lib/generators/deck/templates/rspec.erb +1 -1
  145. data/lib/generators/deck/templates/simplecov.rb.erb +7 -11
  146. data/lib/generators/deck/templates/spec/javascripts/support/decko_jasmine.yml.erb +0 -1
  147. data/lib/generators/mod/USAGE +1 -0
  148. data/lib/{card/tasks → tasks}/card/create.rake +0 -0
  149. data/lib/{card/tasks → tasks}/card/migrate.rake +41 -1
  150. data/lib/{card/tasks → tasks}/card/mod.rake +15 -8
  151. data/lib/tasks/card.rake +65 -0
  152. data/mod/admin/locales/de.yml +4 -0
  153. data/mod/admin/set/all/admin.rb +16 -0
  154. data/mod/admin/set/self/admin.rb +12 -14
  155. data/mod/admin/set/self/admin_info.rb +2 -5
  156. data/mod/core/data/production.yml +7 -0
  157. data/mod/core/data/test.yml +30 -0
  158. data/mod/core/locales/de.yml +28 -0
  159. data/mod/core/locales/en.yml +4 -5
  160. data/mod/core/set/all/assign_attributes.rb +1 -33
  161. data/mod/core/set/all/content.rb +3 -1
  162. data/mod/core/set/all/initialize.rb +1 -4
  163. data/mod/core/set/all/name_events.rb +3 -18
  164. data/mod/core/set/all/reference_events.rb +32 -36
  165. data/mod/core/set/all/subcards.rb +6 -2
  166. data/mod/core/set/all/trash.rb +4 -6
  167. data/mod/core/set/all/type.rb +67 -18
  168. data/mod/core/set/self/version.rb +1 -1
  169. data/mod/core/spec/set/all/name_events_spec.rb +10 -10
  170. data/mod/core/spec/set/all/trash_spec.rb +1 -1
  171. data/mod/core/spec/set/self/trash_spec.rb +1 -1
  172. data/mod/standard/{file → data/files}/favicon/image-icon.png +0 -0
  173. data/mod/standard/{file → data/files}/favicon/image-large.png +0 -0
  174. data/mod/standard/{file → data/files}/favicon/image-medium.png +0 -0
  175. data/mod/standard/{file → data/files}/favicon/image-original.png +0 -0
  176. data/mod/standard/{file → data/files}/favicon/image-small.png +0 -0
  177. data/mod/standard/{file → data/files}/logo/image-original.svg +0 -0
  178. metadata +52 -42
  179. data/db/migrate_core_cards/20150605115802_add_performance_log_card.rb +0 -7
  180. data/lib/card/set/basket.rb +0 -59
  181. data/lib/card/set/code_nest.rb +0 -15
  182. data/lib/card/tasks/card/asset.rake +0 -22
  183. data/lib/card/tasks/card.rake +0 -105
  184. data/lib/card/version.rb +0 -11
  185. data/lib/cardio/commands/USAGE +0 -28
  186. data/lib/cardio/generators/class_methods.rb +0 -35
  187. data/mod/core/spec/set/all/clean_me_spec.rb +0 -258
  188. data/mod/core/spec/set/all/export_spec.rb +0 -71
  189. data/tmpsets/set_pattern/100-all.rb +0 -22
  190. data/tmpsets/set_pattern/101-all_plus.rb +0 -24
  191. data/tmpsets/set_pattern/102-type.rb +0 -40
  192. data/tmpsets/set_pattern/103-star.rb +0 -26
  193. data/tmpsets/set_pattern/104-rstar.rb +0 -28
  194. data/tmpsets/set_pattern/105-rule.rb +0 -28
  195. data/tmpsets/set_pattern/106-right.rb +0 -35
  196. data/tmpsets/set_pattern/107-type_plus_right.rb +0 -43
  197. data/tmpsets/set_pattern/108-self.rb +0 -34
@@ -6,24 +6,26 @@ class Card
6
6
  # NOTE: for all these helpers, method returns *all* fields/children/descendants.
7
7
  # (Not just those current user has permission to read.)
8
8
 
9
- def fields
10
- field_ids.map { |id| Card[id] }
9
+ def field_cards
10
+ field_ids.map(&:card)
11
11
  end
12
12
 
13
13
  def field_names
14
- field_ids.map { |id| Card::Name[id] }
14
+ field_ids.map(&:cardname)
15
15
  end
16
16
 
17
17
  def field_ids
18
18
  child_ids :left
19
19
  end
20
20
 
21
- def each_child &block
21
+ def each_child
22
22
  return unless id
23
23
 
24
- Card.where(
25
- "(left_id = #{id} or right_id = #{id}) and trash is false"
26
- ).each(&block)
24
+ sql = "(left_id = #{id} or right_id = #{id}) and trash is false"
25
+ Card.where(sql).find_each do |card|
26
+ card.include_set_modules
27
+ yield card
28
+ end
27
29
  end
28
30
 
29
31
  # eg, A+B is a child of A and B
@@ -58,7 +58,7 @@ class Card
58
58
  # after_store forces it to save the subcard first
59
59
  # and callback afterwards
60
60
  def with_id_after_store subcard
61
- add_subcard subcard
61
+ subcard subcard
62
62
  subcard.director.after_store { |card| yield card.id }
63
63
  end
64
64
  end
data/lib/card/name/all.rb CHANGED
@@ -7,7 +7,7 @@ class Card
7
7
 
8
8
  # TODO: use delegations and include more name functions
9
9
  delegate :simple?, :compound?, :junction?, to: :name
10
-
10
+ attr_reader :supercard
11
11
  def name
12
12
  @name ||= left_id ? Lexicon.lex_to_name([left_id, right_id]) : super.to_name
13
13
  end
@@ -47,8 +47,9 @@ class Card
47
47
  end
48
48
  end
49
49
 
50
- def update_superleft cardname
51
- @superleft = @supercard if cardname.field_of? @supercard.name
50
+ def update_superleft newname=nil
51
+ newname ||= name
52
+ @superleft = @supercard if newname.field_of? @supercard.name
52
53
  end
53
54
 
54
55
  def update_subcard_names new_name, name_to_replace=nil
@@ -3,10 +3,11 @@ class Card
3
3
  # Name-related Card class methods
4
4
  module CardClass
5
5
  def rename! oldname, newname
6
- Card[oldname].update! name: newname, update_referers: true
6
+ Card[oldname].update! name: newname
7
7
  end
8
8
 
9
9
  def uniquify_name name, rename=:new
10
+ name = name.to_name
10
11
  return name unless Card.exists? name
11
12
 
12
13
  uniq_name = generate_alternative_name name
@@ -12,14 +12,9 @@ class Card
12
12
  end
13
13
 
14
14
  # @return [Card::Name]
15
- def field_name tag_name
16
- case tag_name
17
- when Symbol
18
- trait_name tag_name
19
- else
20
- tag_name = tag_name.to_s[1..-1] if tag_name.to_s[0] == "+"
21
- [self, tag_name].to_name
22
- end
15
+ def field_name tag
16
+ tag = tag.to_s[1..-1] if !tag.is_a?(Symbol) && tag.to_s[0] == "+"
17
+ [self, tag].to_name
23
18
  end
24
19
 
25
20
  # @return [True/False]
@@ -29,10 +24,12 @@ class Card
29
24
  if context.present?
30
25
  absolute_name(context).left_name.key == context.to_name.key
31
26
  else
32
- s.match(/^\s*\+[^+]+$/).present?
27
+ s.match?(/^\s*\+[^+]+$/)
33
28
  end
34
29
  end
35
30
 
31
+ # name is relative name containing only the rightmost part
32
+ # @return [True/False]
36
33
  def field_only?
37
34
  relative? && stripped.to_name.parts.reject(&:blank?).first == parts.last
38
35
  end
@@ -40,27 +37,6 @@ class Card
40
37
  def relative_field_name tag_name
41
38
  field_name(tag_name).name_from self
42
39
  end
43
-
44
- # @return [String]
45
- def trait tag_code
46
- name = trait_name tag_code
47
- name.s
48
- end
49
-
50
- # @return [Card::Name]
51
- def trait_name tag_code
52
- Card::Name[self, tag_code.to_sym]
53
- end
54
-
55
- # @return [True/False]
56
- def trait_name? *traitlist
57
- return false unless compound?
58
-
59
- right_key = right_name.key
60
- traitlist.any? do |codename|
61
- Card::Codename.name(codename)&.key == right_key
62
- end
63
- end
64
40
  end
65
41
  end
66
42
  end
@@ -23,13 +23,17 @@ class Card
23
23
  end
24
24
 
25
25
  def card_id
26
- Card.fetch_id self
26
+ Lexicon.id self
27
27
  end
28
28
 
29
29
  # @return [Symbol] codename of card with name
30
30
  def codename
31
31
  Codename[card_id]
32
32
  end
33
+
34
+ def codename_or_string
35
+ codename || s
36
+ end
33
37
  end
34
38
  end
35
39
  end
data/lib/card/name.rb CHANGED
@@ -19,7 +19,7 @@ class Card
19
19
  case cardish
20
20
  when Card then cardish.name
21
21
  when Symbol, Integer then Card.fetch_name(cardish)
22
- when Array then smart_compose cardish
22
+ when Array then compose cardish
23
23
  when String, NilClass then new cardish
24
24
  else
25
25
  raise ArgumentError, "#{cardish.class} not supported as name identifier"
@@ -40,7 +40,7 @@ class Card
40
40
  str = str.to_s
41
41
 
42
42
  if !validated_parts && str.include?(joint)
43
- compose Cardname.split_parts(str)
43
+ string_compose Cardname.split_parts(str)
44
44
  elsif (id = Card.id_from_string str) # handles ~[id] and :[codename]
45
45
  Card.name_from_id_from_string id, str
46
46
  else
@@ -49,16 +49,16 @@ class Card
49
49
  end
50
50
 
51
51
  # interprets symbols/integers as codenames/ids
52
- def smart_compose parts
52
+ def compose parts
53
53
  new_from_parts(parts) { |part| self[part] }
54
54
  end
55
55
 
56
- def compose parts
56
+ private
57
+
58
+ def string_compose parts
57
59
  new_from_parts(parts) { |part| new part }
58
60
  end
59
61
 
60
- private
61
-
62
62
  def new_from_parts parts, &block
63
63
  name_parts = parts.flatten.map(&block)
64
64
  new name_parts.join(joint), true
@@ -76,13 +76,5 @@ class Card
76
76
  def code
77
77
  Card::Codename[card_id]
78
78
  end
79
-
80
- def setting?
81
- Set::Type::Setting.member_names[key]
82
- end
83
-
84
- def set?
85
- Set::Pattern.card_keys[tag_name.key]
86
- end
87
79
  end
88
80
  end
@@ -93,9 +93,8 @@ class Card
93
93
 
94
94
  def id_from_val val
95
95
  case val
96
- when Integer then val
97
- when String then Card.fetch_id(val) || -999
98
- when Symbol then Card::Codename.id(val) || -999
96
+ when Integer then val
97
+ when String, Symbol then val.card_id || -999
99
98
  end
100
99
  end
101
100
  end
@@ -28,7 +28,7 @@ class Card
28
28
 
29
29
  def normalize_value val
30
30
  case val
31
- when Integer, Float, Hash, Symbol, NilClass then val
31
+ when Integer, Float, Hash, Symbol, NilClass, ActiveRecord::Relation then val
32
32
  when String then normalize_string_value val
33
33
  when Array then normalize_array_value val
34
34
  else raise Error::BadQuery, "Invalid value type: #{val.class} (#{val.inspect})"
@@ -18,12 +18,15 @@ class Card
18
18
  module Order
19
19
  def order
20
20
  full_syntax do
21
- "ORDER BY #{order_directives.join ', '}"
21
+ dirs = order_directives
22
+ "ORDER BY #{dirs.join ', '}" if dirs.present?
22
23
  end
23
24
  end
24
25
 
25
26
  def order_directives
26
- Array.wrap(order_config).map do |order_key|
27
+ return if @mods[:sort].blank?
28
+
29
+ Array.wrap(@mods[:sort]).map do |order_key|
27
30
  order_directive order_key
28
31
  end
29
32
  end
@@ -58,10 +61,6 @@ class Card
58
61
  safe_sql @mods[:dir]
59
62
  end
60
63
  end
61
-
62
- def order_config
63
- @mods[:sort].blank? ? "update" : @mods[:sort]
64
- end
65
64
  end
66
65
  end
67
66
  end
@@ -32,9 +32,10 @@ class Card
32
32
 
33
33
  def parse_value value
34
34
  case value
35
- when Array then parse_array_value value.clone
36
- when nil then ["is", nil]
37
- else ["=", parse_simple_value(value)]
35
+ when Array then parse_array_value value.clone
36
+ when ActiveRecord::Relation then ["in", value]
37
+ when nil then ["is", nil]
38
+ else ["=", parse_simple_value(value)]
38
39
  end
39
40
  end
40
41
 
@@ -48,7 +49,8 @@ class Card
48
49
  when String, Integer then value
49
50
  when Symbol then value.to_s
50
51
  when nil then nil
51
- else raise Error::BadQuery, "Invalid property value: #{value.inspect}"
52
+ else
53
+ raise Error::BadQuery, "Invalid property value: #{value.inspect}"
52
54
  end
53
55
  end
54
56
 
@@ -66,9 +68,10 @@ class Card
66
68
 
67
69
  def sqlize v
68
70
  case v
69
- when Query then v.to_sql
70
- when Array then sqlize_array v
71
- when nil then "NULL"
71
+ when Query then v.to_sql
72
+ when ActiveRecord::Relation then "(#{v.to_sql})"
73
+ when Array then sqlize_array v
74
+ when nil then "NULL"
72
75
  else quote(v.to_s)
73
76
  end
74
77
  end
@@ -21,7 +21,7 @@ class Card
21
21
  end
22
22
 
23
23
  def referer_cards_from_references references
24
- references.map(&:referer_id).uniq.map(&Card.method(:fetch)).compact
24
+ references.map(&:referer_id).uniq.map(&:card).compact
25
25
  end
26
26
 
27
27
  # cards that self refers to
@@ -62,11 +62,13 @@ class Card
62
62
  Reference.mass_insert reference_values_array(ref_hash)
63
63
  end
64
64
 
65
- # delete references from this card
66
- def delete_references_out
67
- return unless id.present?
68
-
69
- Reference.where(referer_id: id).delete_all
65
+ # replace references in card content
66
+ def swap_names old_name, new_name
67
+ cont = content_object
68
+ cont.find_chunks(:Reference).each do |chunk|
69
+ chunk.swap_name old_name, new_name
70
+ end
71
+ cont.to_s
70
72
  end
71
73
 
72
74
  private
@@ -122,7 +124,7 @@ class Card
122
124
  end
123
125
 
124
126
  # Partial references are needed to track references to virtual cards.
125
- # For example a link to virual card [[A+*self]] won't have a referee_id,
127
+ # For example a link to virtual card [[A+*self]] won't have a referee_id,
126
128
  # but when A's name is changed we have to find and update that link.
127
129
  def interpret_partial_references ref_hash, referee_name
128
130
  return if referee_name.simple?
@@ -4,17 +4,21 @@ class Card
4
4
  # a Reference is a directional relationship from one card (the referer)
5
5
  # to another (the referee).
6
6
  class Reference < Cardio::Record
7
+ # card that refers
8
+ def referer
9
+ Card[referer_id]
10
+ end
11
+
12
+ # card that is referred to
13
+ def referee
14
+ Card[referee_id]
15
+ end
16
+
7
17
  class << self
8
18
  # bulk insert improves performance considerably
9
19
  # array takes form [ [referer_id, referee_id, referee_key, ref_type], ...]
10
20
  def mass_insert array
11
- return if array.empty?
12
-
13
- value_statements = array.map { |values| "\n(#{values.join ', '})" }
14
- sql = "INSERT into card_references "\
15
- "(referer_id, referee_id, referee_key, ref_type) "\
16
- "VALUES #{value_statements.join ', '}"
17
- Card.connection.execute sql
21
+ Card.connection.execute mass_insert_sql(array) if array.present?
18
22
  end
19
23
 
20
24
  # map existing reference to name to card via id
@@ -27,22 +31,10 @@ class Card
27
31
  where(referee_id: referee_id).update_all referee_id: nil
28
32
  end
29
33
 
30
- # find all references to missing (eg deleted) cards and reset them
31
- def unmap_if_referee_missing
32
- joins(
33
- "LEFT JOIN cards ON card_references.referee_id = cards.id"
34
- ).where(
35
- "(cards.id IS NULL OR cards.trash IS TRUE) AND referee_id IS NOT NULL"
36
- ).update_all referee_id: nil
37
- end
38
-
39
- # remove all references from missing (eg deleted) cards
40
- def delete_if_referer_missing
41
- joins(
42
- "LEFT JOIN cards ON card_references.referer_id = cards.id"
43
- ).where(
44
- "cards.id IS NULL"
45
- ).pluck_in_batches(:id) do |group_ids|
34
+ # remove reference to and from missing cards
35
+ def clean
36
+ missing(:referee_id).where("referee_id IS NOT NULL").update_all referee_id: nil
37
+ missing(:referer_id).pluck_in_batches(:id) do |group_ids|
46
38
  # used to be .delete_all here, but that was failing on large dbs
47
39
  Rails.logger.info "deleting batch of references"
48
40
  where("id in (#{group_ids.join ','})").delete_all
@@ -52,34 +44,37 @@ class Card
52
44
  # repair references one by one (delete, create, delete, create...)
53
45
  # slower, but better than #recreate_all for use on running sites
54
46
  def repair_all
55
- delete_if_referer_missing
56
- Card.where(trash: false).find_each do |card|
57
- Rails.logger.info "updating references from #{card}"
58
- card.include_set_modules
59
- card.update_references_out
60
- end
47
+ clean
48
+ each_card(&:update_references_out)
61
49
  end
62
50
 
63
51
  # delete all references, then recreate them one by one
64
52
  # faster than #repair_all, but not recommended for use on running sites
65
53
  def recreate_all
66
54
  delete_all
55
+ each_card(&:create_references_out)
56
+ end
57
+
58
+ private
59
+
60
+ # find all references to or from missing (eg deleted) cards
61
+ def missing field
62
+ joins("LEFT JOIN cards ON card_references.#{field} = cards.id")
63
+ .where("(cards.id IS NULL OR cards.trash IS TRUE)")
64
+ end
65
+
66
+ def each_card
67
67
  Card.where(trash: false).find_each do |card|
68
- Rails.logger.info "updating references from #{card}"
69
- card.include_set_modules
70
- card.create_references_out
68
+ Rails.logger.debug "references from #{card.name}"
69
+ yield card.include_set_modules
71
70
  end
72
71
  end
73
- end
74
-
75
- # card that refers
76
- def referer
77
- Card[referer_id]
78
- end
79
72
 
80
- # card that is referred to
81
- def referee
82
- Card[referee_id]
73
+ def mass_insert_sql array
74
+ value_statements = array.map { |values| "\n(#{values.join ', '})" }
75
+ "INSERT into card_references (referer_id, referee_id, referee_key, ref_type) " \
76
+ "VALUES #{value_statements.join ', '}"
77
+ end
83
78
  end
84
79
  end
85
80
  end
data/lib/card/rule/all.rb CHANGED
@@ -64,9 +64,9 @@ class Card
64
64
  end
65
65
 
66
66
  def rule_id_lookup lookup_hash, cache_suffix, fallback_suffix=nil
67
- rule_set_keys.each do |rule_set_key|
68
- rule_id = lookup_hash["#{rule_set_key}+#{cache_suffix}"]
69
- rule_id ||= fallback_suffix && lookup_hash["#{rule_set_key}+#{fallback_suffix}"]
67
+ rule_lookup_keys.each do |lookup_key|
68
+ rule_id = lookup_hash["#{lookup_key}+#{cache_suffix}"]
69
+ rule_id ||= fallback_suffix && lookup_hash["#{lookup_key}+#{fallback_suffix}"]
70
70
  return rule_id if rule_id
71
71
  end
72
72
  nil
@@ -2,6 +2,11 @@ class Card
2
2
  module Set
3
3
  # advanced set module API
4
4
  module AdvancedApi
5
+ def assign_type type, module_key=nil
6
+ module_key ||= shortname
7
+ Type.assignment[module_key] = type.card_id
8
+ end
9
+
5
10
  def setting_opts opts
6
11
  extend Card::Setting
7
12
  register_setting opts
@@ -0,0 +1,13 @@
1
+ class Card
2
+ module Set
3
+ # Set-related methods included in card class
4
+ # (note: Card::Set::All would follow our naming convention but is in use by the
5
+ # "all" set)
6
+ module CardMethods
7
+ include Event::All
8
+ include Pattern::All
9
+
10
+ delegate :basket, to: Set
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,14 @@
1
1
  class Card
2
2
  # attributes that ActiveJob can handle
3
+ #
4
+ # supercard and superleft are excluded, because it caused issues to have them in
5
+ # delayed job but not fully restored (set modules not included, attributes not retained,
6
+ # etc.) Since we're supposed to have an actual _left_ by the integrate_with_delay
7
+ # stage, it's not clear that they're needed. But if we revisit and find they _are_
8
+ # needed, then we clearly need to make sure that they are fully restored. At a bare
9
+ # minimum they would need to include set modules.
3
10
  def serializable_attributes
4
- self.class.action_specific_attributes + set_specific.keys
11
+ self.class.action_specific_attributes + set_specific.keys - %i[supercard superleft]
5
12
  end
6
13
 
7
14
  module Set
@@ -34,6 +34,14 @@ class Card
34
34
  @trigger_hash ||= hash_with_value trigger, true
35
35
  end
36
36
 
37
+ def skip_event? event
38
+ full_skip_hash.key? event.to_s
39
+ end
40
+
41
+ def trigger_event? event
42
+ full_trigger_hash.key? event.to_s
43
+ end
44
+
37
45
  private
38
46
 
39
47
  # "applies always means event can run
@@ -168,6 +168,7 @@ class Card
168
168
  def rescuing_integration
169
169
  yield
170
170
  rescue StandardError => e
171
+ # puts "integration error: #{e.message}".red
171
172
  Card::Error.report e, self
172
173
  ensure
173
174
  true
@@ -75,7 +75,7 @@ class Card
75
75
  def define_wrap_with_method wrapper_name, wrapper_method_name
76
76
  class_exec(self) do |_format|
77
77
  define_method "wrap_with_#{wrapper_name}" do |*args, &interior|
78
- @interior, opts = interior ? [interior.call, args.first] : args
78
+ voo.interior, opts = interior ? [interior.call, args.first] : args
79
79
  send_wrapper_method wrapper_method_name, opts
80
80
  end
81
81
  end
@@ -7,12 +7,13 @@ class Card
7
7
  # Whenever you create a format block in a set module in a {Cardio::Mod mod}, you
8
8
  # create a format module that is extended with AbstractFormat.
9
9
  module AbstractFormat
10
- include Set::Basket
11
10
  include ViewOpts
12
11
  include ViewDefinition
13
12
  include HamlViews
14
13
  include Wrapper
15
14
 
15
+ delegate :basket, to: Set
16
+
16
17
  # _Views_ are the primary way that both sharks and monkeys interact with cards.
17
18
  # Sharks select views to use in _nests_. Monkeys can define and tweak those
18
19
  # views. These docs will introduce the basics of view definition.
@@ -114,13 +114,12 @@ class Card
114
114
 
115
115
  # make mod ready to include in base (non-set-specific) format classes
116
116
  def register_all_set_format format_class, mod
117
- add_to_array_val modules[:base_format], format_class, mod
117
+ add_to_array_val Set.modules[:base_format], format_class, mod
118
118
  end
119
119
 
120
120
  def register_standard_set_format format_class, mod
121
- format_type = abstract_set? ? :abstract_format : :nonbase_format
122
121
  # ready to include dynamically in set members' format singletons
123
- format_hash = modules[format_type][format_class] ||= {}
122
+ format_hash = Set.modules[set_format_type_key][format_class] ||= {}
124
123
  add_to_array_val format_hash, shortname, mod
125
124
  end
126
125
 
@@ -19,6 +19,20 @@ class Card
19
19
  Pattern.find(pattern_code).anchor_parts_count
20
20
  end
21
21
 
22
+ def set_format_type_key
23
+ @set_format_type_key ||= :"#{set_type_key}_format"
24
+ end
25
+
26
+ def set_type_key
27
+ if all_set?
28
+ :base
29
+ elsif abstract_set?
30
+ :abstract
31
+ else
32
+ :nonbase
33
+ end
34
+ end
35
+
22
36
  def set_name_parts
23
37
  @set_name_parts ||= name.split "::"
24
38
  end
@@ -39,6 +53,60 @@ class Card
39
53
  def respond_to_missing? method_name, _include_private=false
40
54
  method_name.match? SET_PATTERN_TEST_REGEXP
41
55
  end
56
+
57
+ def modules
58
+ if all_set?
59
+ [self]
60
+ elsif abstract_set?
61
+ [test_set]
62
+ else
63
+ Set.modules[:nonbase][shortname] || []
64
+ end
65
+ end
66
+
67
+ def test_set
68
+ # rubocop:disable Lint/Eval
69
+ ::Card::Set::Self.const_remove_if_defined :TestSet
70
+ eval <<-RUBY, binding, __FILE__, __LINE__ + 1
71
+ class ::Card::Set::Self
72
+ module TestSet
73
+ extend Card::Set
74
+ include_set #{name}
75
+ end
76
+ end
77
+ RUBY
78
+ ::Card::Set::Self::TestSet
79
+ # rubocop:enable Lint/Eval
80
+ end
81
+
82
+ def format_modules format_sym, test: true
83
+ if base_format_modules?
84
+ [format_module(format_sym)]
85
+ elsif abstract_set?
86
+ abstract_format_modules format_sym, test
87
+ else
88
+ nonbase_format_modules format_sym
89
+ end
90
+ end
91
+
92
+ def format_module format_sym
93
+ const_get Card::Format.format_class_name(format_sym)
94
+ end
95
+
96
+ private
97
+
98
+ def base_format_modules?
99
+ !set_format_type_key || set_format_type_key == :base_format
100
+ end
101
+
102
+ def abstract_format_modules format_sym, test
103
+ [(test ? test_set : self).format_module(format_sym)]
104
+ end
105
+
106
+ def nonbase_format_modules format_sym
107
+ format_class = Card::Format.format_class format: format_sym
108
+ Card::Set.modules[set_format_type_key][format_class][shortname] || []
109
+ end
42
110
  end
43
111
  end
44
112
  end
@@ -74,7 +74,7 @@ class Card
74
74
  def each_format_with_mods set
75
75
  set_type = set.abstract_set? ? :abstract : :nonbase
76
76
  format_type = "#{set_type}_format".to_sym
77
- modules[format_type].each_pair { |*args| yield(*args) }
77
+ Set.modules[format_type].each_pair { |*args| yield(*args) }
78
78
  end
79
79
 
80
80
  def applicable_format? format, except, only