card 1.19.4 → 1.19.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/01_core_extensions/module.rb +4 -0
  4. data/lib/card.rb +2 -2
  5. data/lib/card/content/diff/lcs.rb +1 -1
  6. data/lib/card/model/save_helper.rb +100 -25
  7. data/lib/card/name.rb +8 -0
  8. data/lib/card/set/event.rb +22 -42
  9. data/lib/card/set/format.rb +1 -0
  10. data/lib/card/set/inheritance.rb +30 -5
  11. data/lib/card/set/loader.rb +24 -3
  12. data/mod/account/set/self/account_links.rb +45 -21
  13. data/mod/account/set/self/signin.rb +5 -9
  14. data/mod/account/set/type/signup.rb +22 -15
  15. data/mod/account/spec/set/all/account_spec.rb +3 -1
  16. data/mod/admin/set/self/admin.rb +4 -4
  17. data/mod/admin/set/self/admin_info.rb +3 -9
  18. data/mod/admin/set/self/trash.rb +21 -14
  19. data/mod/basic_formats/set/all/base.rb +6 -7
  20. data/mod/bootstrap/set/all/bootstrap/helper.rb +4 -5
  21. data/mod/bootstrap/set/all/bootstrap/tabs.rb +3 -4
  22. data/mod/bootstrap/spec/set/all/bootstrap/form_spec.rb +2 -0
  23. data/mod/carrierwave/set/abstract/attachment/storage_type.rb +3 -0
  24. data/mod/core/chunk/link.rb +3 -3
  25. data/mod/core/chunk/uri.rb +2 -2
  26. data/mod/core/set/all/actify.rb +11 -10
  27. data/mod/core/set/all/permissions.rb +6 -7
  28. data/mod/core/spec/set/all/actify_spec.rb +2 -0
  29. data/mod/developer/set/right/debug.rb +1 -1
  30. data/mod/email/set/all/follow.rb +2 -1
  31. data/mod/email/set/right/follow.rb +19 -22
  32. data/mod/email/set/type_plus_right/user/follow.rb +1 -1
  33. data/mod/email/spec/set/all/notify_spec.rb +17 -14
  34. data/mod/history/set/all/history.rb +35 -38
  35. data/mod/machines/spec/set/abstract/machine_spec.rb +2 -0
  36. data/mod/settings/set/abstract/permission.rb +6 -9
  37. data/mod/settings/set/type/setting.rb +4 -3
  38. data/mod/solid_cache/set/abstract/solid_cache.rb +41 -20
  39. data/mod/solid_cache/spec/set/abstract/solid_cache_spec.rb +3 -1
  40. data/mod/standard/set/all/error.rb +14 -19
  41. data/mod/standard/set/all/links.rb +149 -120
  42. data/mod/standard/set/all/rich_html/content.rb +9 -19
  43. data/mod/standard/set/all/rich_html/header.rb +3 -5
  44. data/mod/standard/set/all/rich_html/menu.rb +25 -23
  45. data/mod/standard/set/all/rich_html/modal.rb +11 -9
  46. data/mod/standard/set/all/rich_html/toolbar.rb +85 -84
  47. data/mod/standard/set/rstar/rules_editor.rb +96 -79
  48. data/mod/standard/set/type/cardtype.rb +2 -1
  49. data/mod/standard/set/type/search_type.rb +2 -1
  50. data/mod/standard/set/type/set.rb +15 -19
  51. data/mod/standard/set/type/uri.rb +2 -2
  52. data/mod/standard/spec/set/all/links_spec.rb +8 -5
  53. data/spec/config/initializers/core_extensions_spec.rb +2 -0
  54. data/spec/lib/card/format/nest_spec.rb +2 -0
  55. data/spec/lib/card/migration/import_spec.rb +2 -0
  56. data/spec/lib/card/set/trait_spec.rb +2 -0
  57. data/spec/lib/card/stage_director_spec.rb +2 -0
  58. data/spec/lib/card/view_cache_spec.rb +2 -0
  59. data/spec/spec_helper.rb +11 -139
  60. data/spec/support/card_spec_helper.rb +61 -0
  61. data/spec/support/card_spec_loader.rb +83 -0
  62. data/spec/support/helper/card_helper.rb +87 -0
  63. data/spec/support/helper/event_helper.rb +80 -0
  64. data/spec/support/helper/render_helper.rb +35 -0
  65. data/spec/support/helper/save_helper.rb +26 -0
  66. data/{config → spec/support}/simplecov_helper.rb +1 -1
  67. metadata +16 -5
  68. data/spec/card_spec_helper.rb +0 -137
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2438311a0c0d3270f1d65eb41fbe38914740135f
4
- data.tar.gz: 75fa9bdbf0fd463f171b47875624bb96025b50c9
3
+ metadata.gz: 4de6e0031d77758dbc7c4ca11a084e2e24cd13ae
4
+ data.tar.gz: e33dd67fb7b2c868d12d4db50e574c0bc6cfb69b
5
5
  SHA512:
6
- metadata.gz: bec0abeaa624791be2ba54a2709fd6c3d75f39b07c53f758e7464c75ede3573eb84c16c048be5f3843141f9e4d715d5744004f3009c6a935c370d405fd4f02fe
7
- data.tar.gz: 49c9dcec44ea2e97f112e14c8e5f7c1b7281fb07445172c2b7b3eda79cba2ea67116dc1a32b133039387050674b4c6cf8b96087f700066126fafe3e8b36ac8bd
6
+ metadata.gz: eeaafba60cf7defa62e9d63756bcfb184cc84705191fef1503e44d4e60bd4229a1f727f6b7eaa618720781fb62e6899f6676e6bfae6452da7d0a5d00800a026f
7
+ data.tar.gz: 023ddaf342ae2eed8174132b2a438b7b663809195806e85fd24c3535cd26f0d36352b01e8bfe7c4598f0c0659034c4f2cab77b238048142be3dd724b29193d9a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.19.4
1
+ 1.19.5
@@ -7,6 +7,10 @@ module CoreExtensions
7
7
  const_get(*args) if const_defined?(*args)
8
8
  end
9
9
 
10
+ def const_remove_if_defined const
11
+ remove_const const if const_defined? const
12
+ end
13
+
10
14
  def const_get_or_set const
11
15
  const_get_if_defined(const) || const_set(const, yield)
12
16
  end
@@ -8,7 +8,7 @@ require "carrierwave"
8
8
  # end
9
9
  # end
10
10
 
11
- Object.send :remove_const, :Card if Object.send(:const_defined?, :Card)
11
+ Object.const_remove_if_defined :Card
12
12
 
13
13
  # Cards are wiki-inspired building blocks.
14
14
  #
@@ -69,7 +69,7 @@ class Card < ActiveRecord::Base
69
69
  attr_accessor :follower_stash
70
70
 
71
71
  define_callbacks(
72
- :select_action, :show_page, :handle, :act,
72
+ :select_action, :show_page, :act,
73
73
 
74
74
  # VALIDATION PHASE
75
75
  :initialize_stage, :prepare_to_validate_stage, :validate_stage,
@@ -3,7 +3,7 @@ require_dependency "card/content/diff/processor"
3
3
  class Card
4
4
  class Content
5
5
  class Diff
6
- # Use LCS algorithm to create a Diff::Result
6
+ # Use LCS algorithm to create a {Diff::Result}
7
7
  class LCS
8
8
  def initialize opts
9
9
  # regex; remove matches completely from diff
@@ -1,48 +1,113 @@
1
1
  class Card
2
2
  module Model
3
+ # API to create and update cards.
4
+ # It is intended as a helper for "external" scripts
5
+ # (seeding, testing, migrating, etc) and not for internal application code.
6
+ # The general pattern is:
7
+ # All methods use the ActiveRecord !-methods that throw exceptions if
8
+ # somethings fails.
9
+ # All !-methods in this module rename existing cards
10
+ # to resolve name conflicts)
3
11
  module SaveHelper
4
- def create_card args
12
+ def create_card name_or_args, content_or_args=nil
13
+ args = standardize_args name_or_args, content_or_args
5
14
  resolve_name_conflict args
6
15
  Card.create! args
7
16
  end
8
17
 
18
+ def update_card name, content_or_args
19
+ args = standardize_update_args content_or_args
20
+ resolve_name_conflict args
21
+ Card[name].update_attributes! args
22
+ end
23
+
24
+ def create_or_update_card name_or_args, content_or_args=nil
25
+ args = standardize_args name_or_args, content_or_args
26
+ if Card[args[:name]]
27
+ update_card(args.delete(:name), args)
28
+ else
29
+ create_card(args)
30
+ end
31
+ end
32
+
33
+ def delete_card name
34
+ return unless (card = Card[name])
35
+ card.delete!
36
+ end
37
+
38
+ def delete_code_card name
39
+ update name, codename: nil
40
+ delete name
41
+ end
42
+
43
+ # create if card doesn't exist
44
+ # updates existing card only if given attributes are different except the
45
+ # name
46
+ # For example if a card with name "under_score" exists
47
+ # then `ensure_card "Under Score"` doesn't change anything
48
+ def ensure_card name_or_args, content_or_args=nil
49
+ args = standardize_args name_or_args, content_or_args
50
+ name = args.delete(:name)
51
+ if (card = Card[name])
52
+ ensure_attributes card, args
53
+ else
54
+ Card.create! args.merge(name: name)
55
+ end
56
+ end
57
+
58
+ # create if card doesn't exist
59
+ # updates existing card only if given attributes are different including
60
+ # the name
61
+ # For example if a card with name "under_score" exists
62
+ # then `ensure_card "Under Score"` renames it to "Under Score"
63
+ def ensure_card! name_or_args, content_or_args=nil
64
+ args = standardize_args name_or_args, content_or_args
65
+ if (card = Card[args[:name]])
66
+ ensure_attributes card, args
67
+ else
68
+ Card.create! args
69
+ end
70
+ end
71
+
9
72
  # if card with same name exists move it out of the way
10
- def create_card! args
73
+ def create_card! name_or_args, content_or_args=nil
74
+ args = standardize_args name_or_args, content_or_args
11
75
  create_card args.reverse_merge(rename_if_conflict: :old)
12
76
  end
13
77
 
14
- def update_card name, args
15
- resolve_name_conflict args
16
- Card[name].update_attributes! args
78
+ def update_card! name, content_or_args
79
+ args = standardize_update_args content_or_args
80
+ update_card name, args.reverse_merge(rename_if_conflict: :new)
17
81
  end
18
82
 
19
- def update_card! args
20
- update_card args.reverse_merge(rename_if_conflict: :new)
83
+ def create_or_update_card! name_or_args, content_or_args=nil
84
+ args = standardize_args name_or_args, content_or_args
85
+ create_or_update args.reverse_merge(rename_if_conflict: :new)
21
86
  end
22
87
 
23
- def create_or_update name_or_args, args={}
88
+ # @return args
89
+ def standardize_args name_or_args, content_or_args
24
90
  if name_or_args.is_a?(Hash)
25
- name = name_or_args.delete :name
26
- args = name_or_args
91
+ name_or_args
27
92
  else
28
- name = name_or_args
93
+ add_name name_or_args, content_or_args
29
94
  end
30
- if Card[name]
31
- update_card name, args
95
+ end
96
+
97
+ def standardize_update_args content_or_args
98
+ if content_or_args.is_a?(String)
99
+ { content: content_or_args }
32
100
  else
33
- create_card args.merge(name: name)
101
+ content_or_args
34
102
  end
35
103
  end
36
104
 
37
- def create_or_update! name_or_args, args=nil
38
- if name_or_args.is_a?(Hash)
39
- name = name_or_args.delete(:name)
40
- args = name_or_args
105
+ def add_name name, content_or_args
106
+ if content_or_args.is_a?(String)
107
+ { content: content_or_args, name: name }
41
108
  else
42
- name = name_or_args
43
- args ||= {}
109
+ content_or_args.merge name: name
44
110
  end
45
- create_or_update name, args.reverse_merge(rename_if_conflict: :new)
46
111
  end
47
112
 
48
113
  def resolve_name_conflict args
@@ -51,11 +116,21 @@ class Card
51
116
  args[:name] = Card.uniquify_name args[:name], rename
52
117
  end
53
118
 
54
- # create if it doesn't exist
55
- def ensure_card args
56
- return if Card[args[:name]]
57
- Card.create! args
119
+ def ensure_attributes card, args
120
+ update_args = args.select { |key, value| card.send(key) != value }
121
+ return if update_args.empty?
122
+ card.update_attributes! update_args
58
123
  end
124
+
125
+ alias_method :create, :create_card
126
+ alias_method :update, :update_card
127
+ alias_method :create_or_update, :create_or_update_card
128
+ alias_method :create!, :create_card!
129
+ alias_method :update!, :update_card!
130
+ alias_method :create_or_update!, :create_or_update_card!
131
+ alias_method :ensure, :ensure_card
132
+ alias_method :ensure!, :ensure_card!
133
+ alias_method :delete, :delete_card
59
134
  end
60
135
  end
61
136
  end
@@ -11,6 +11,14 @@ class Card
11
11
  self.session = proc { Card::Auth.current.name }
12
12
  self.banned_array = ["/"]
13
13
 
14
+ def self.cardish mark
15
+ case mark
16
+ when Card then mark.cardname
17
+ when Symbol, Integer then Card.quick_fetch(mark).cardname
18
+ else mark.to_name
19
+ end
20
+ end
21
+
14
22
  def star?
15
23
  simple? && "*" == s[0, 1]
16
24
  end
@@ -62,12 +62,10 @@ class Card
62
62
 
63
63
  if with_delay? opts
64
64
  delaying_method = "#{event}_with_delay"
65
- define_event_delaying_method event, delaying_method
66
- define_event_method event, delaying_method
67
- define_active_job event, final_method_name, opts[:queue_as]
68
- else
69
- define_event_method event, final_method_name
65
+ define_event_delaying_method event, delaying_method, final_method_name
66
+ final_method_name = delaying_method
70
67
  end
68
+ define_event_method event, final_method_name
71
69
  end
72
70
 
73
71
  def with_delay? opts
@@ -84,17 +82,6 @@ class Card
84
82
  opts[:on] = [:create, :update] if opts[:on] == :save
85
83
  end
86
84
 
87
- def define_event_delaying_method event, method_name
88
- class_eval do
89
- define_method(method_name, proc do
90
- Object.const_get(event.to_s.camelize).perform_later(
91
- self, serialize_for_active_job, Card::Env.serialize,
92
- Card::Auth.current_id
93
- )
94
- end)
95
- end
96
- end
97
-
98
85
  def define_event_method event, call_method
99
86
  class_eval do
100
87
  define_method event do
@@ -106,38 +93,31 @@ class Card
106
93
  end
107
94
  end
108
95
 
109
- # creates an Active Job.
96
+ # creates an ActiveJob.
110
97
  # The scheduled job gets the card object as argument and all serializable
111
98
  # attributes of the card.
112
99
  # (when the job is executed ActiveJob fetches the card from the database
113
100
  # so all attributes get lost)
114
- # @param name [String] the name for the ActiveJob child class
115
- # @param final_method [String] the name of the card instance method to be
116
- # queued
117
- # @option queue [Symbol] (:default) the name of the queue
118
- def define_active_job name, final_method, queue=:integrate_with_delay
119
- class_name = name.to_s.camelize
120
- define_active_job_class class_name, queue || :integrate_with_delay
121
- define_active_job_perform_method class_name, final_method
122
- end
123
-
124
- def define_active_job_class class_name, queue
125
- eval %(
126
- class ::#{class_name} < ActiveJob::Base
127
- queue_as :#{queue}
128
- end
129
- )
101
+ # @param event [String] the event used as queue name
102
+ # @param method_name [String] the name of the method we define to trigger
103
+ # the actjve job
104
+ # @param final_method_name [String] the name of the method that get called
105
+ # by the active job and finally executes the event
106
+ def define_event_delaying_method event, method_name, final_method_name
107
+ class_eval do
108
+ define_method(method_name, proc do
109
+ IntegrateWithDelayJob.set(queue: event).perform_later(
110
+ self, serialize_for_active_job, Card::Env.serialize,
111
+ Card::Auth.current_id, final_method_name
112
+ )
113
+ end)
114
+ end
130
115
  end
131
116
 
132
- def define_active_job_perform_method class_name, method_name
133
- Object.const_get(class_name).class_eval do
134
- define_method(
135
- :perform,
136
- proc do |card, card_attribs, env, current_id|
137
- card.deserialize_for_active_job! card_attribs, env, current_id
138
- card.send method_name
139
- end
140
- )
117
+ class IntegrateWithDelayJob < ActiveJob::Base
118
+ def perform card, card_attribs, env, current_id, method_name
119
+ card.deserialize_for_active_job! card_attribs, env, current_id
120
+ card.send method_name
141
121
  end
142
122
  end
143
123
 
@@ -21,6 +21,7 @@ class Card
21
21
  #
22
22
  module Format
23
23
  def format *format_names, &block
24
+ format_names.compact!
24
25
  if format_names.empty?
25
26
  format_names = [:base]
26
27
  elsif format_names.first == :all
@@ -4,12 +4,37 @@ class Card
4
4
  module Inheritance
5
5
  # include a set module and all its format modules
6
6
  # @param [Module] set
7
- # @param [Hash] opts choose the formats you want to include
7
+ # @param [Hash] opts choose the formats you want to include. You can also
8
+ # pass arbitrary options to the included set. The option is saved
9
+ # in the including set. To use the option you need a `included` method
10
+ # in the included set to fetch the option.
8
11
  # @option opts [Symbol, Array<Symbol>] :only include only these formats
9
12
  # @option opts [Symbol, Array<Symbol>] :except don't include these formats
10
- # #@example
11
- # include_set Type::Basic, except: :css
13
+ # @example
14
+ # include_set Type::Basic, except: :css
15
+ # @example pass an option
16
+ # include_set Type::Name, default_name: "Luke"
17
+ # default_name # => "Luke"
18
+ #
19
+ # def introduce_yourself
20
+ # puts my_name_is # => "Luke"
21
+ # end
22
+ #
23
+ # # in Type::Name
24
+ # def self.included host_class
25
+ # host_class.class_eval do
26
+ # define_method :my_name_is do |name=nil|
27
+ # name || host_class.default_name
28
+ # end
29
+ # end
30
+ # end
31
+ #
12
32
  def include_set set, opts={}
33
+ opts.each do |key, value|
34
+ cattr_accessor key
35
+ send "#{key}=", value
36
+ end
37
+
13
38
  set_type = set.abstract_set? ? :abstract : :nonbase
14
39
  add_set_modules Card::Set.modules[set_type][set.shortname]
15
40
  include_set_formats set, opts
@@ -20,8 +45,8 @@ class Card
20
45
  # @param [Hash] opts choose the formats you want to include
21
46
  # @option opts [Symbol, Array<Symbol>] :only include only these formats
22
47
  # @option opts [Symbol, Array<Symbol>] :except don't include these formats
23
- # #@example
24
- # include_set Type::Basic, except: :css
48
+ # @example
49
+ # include_set_formats Type::Basic, except: :css
25
50
  def include_set_formats set, opts={}
26
51
  each_format set do |format, format_mods|
27
52
  format_sym = Card::Format.format_sym format
@@ -52,15 +52,36 @@ class Card
52
52
  end
53
53
 
54
54
  def tmp_file_template pattern, modules, content_path
55
+ content = File.read(content_path)
56
+ wrapped_content = tmp_file_wrapped_content content_path, content
57
+
58
+ # TODO: load directly without tmp file
59
+ return wrapped_content if content =~ /\A#!\s?simple load/
60
+
55
61
  submodules = modules.map { |m| "module #{m};" }
62
+ if content =~ /\A#!\s?not? set module/
63
+ submodules.pop
64
+ else
65
+ submodules[-1] += " extend Card::Set"
66
+ end
67
+ tmp_file_frame pattern, submodules, wrapped_content
68
+ end
69
+
70
+ def tmp_file_frame pattern, submodules, content
56
71
  <<-RUBY
57
72
  # -*- encoding : utf-8 -*-
58
- class Card; module Set; class #{pattern}; #{submodules * ' '} extend Card::Set
73
+ class Card; module Set; class #{pattern}; #{submodules.join ' '}
74
+ #{content}
75
+ end;end;end;#{'end;' * submodules.size}
76
+ RUBY
77
+ end
78
+
79
+ def tmp_file_wrapped_content content_path, content
80
+ <<-RUBY
59
81
  # ~~ above autogenerated; below pulled from #{content_path} ~~
60
- #{File.read content_path}
82
+ #{content}
61
83
 
62
84
  # ~~ below autogenerated; above pulled from #{content_path} ~~
63
- end;end;end;#{'end;' * submodules.size}
64
85
  RUBY
65
86
  end
66
87
 
@@ -11,36 +11,60 @@ format :html do
11
11
  end
12
12
 
13
13
  view :sign_up, perms: ->(r) { r.show_signup_link? },
14
- denial: :blank do |_args|
15
- # 'Sign up'
16
- link_to(I18n.t(:sign_up, scope: "mod.standard.set.self.account_links"),
17
- card_path("account/signup"), id: "signup-link")
14
+ denial: :blank do |args|
15
+ link_to_card :signup, args[:link_text], args[:link_opts]
18
16
  end
19
17
 
20
18
  view :sign_in, perms: ->(_r) { !Auth.signed_in? },
21
- denial: :blank do |_args|
22
- # 'Sign in'
23
- link_to(I18n.t(:sign_in, scope: "mod.standard.set.self.account_links"),
24
- card_path(":signin"), id: "signin-link")
19
+ denial: :blank do |args|
20
+ link_to_card :signin, args[:link_text], args[:link_opts]
25
21
  end
26
22
 
27
- view :invite, perms: ->(r) { r.show_invite_link? },
28
- denial: :blank do |_args|
29
- # 'Invite'
30
- link_to(I18n.t(:invite, scope: "mod.standard.set.self.account_links"),
31
- card_path("account/signup"), id: "invite-a-friend-link")
23
+ view :sign_out, perms: ->(_r) { Auth.signed_in? },
24
+ denial: :blank do |args|
25
+ link_to_card :signin, args[:link_text], args[:link_opts]
32
26
  end
33
27
 
34
- view :sign_out, perms: ->(_r) { Auth.signed_in? },
35
- denial: :blank do |_args|
36
- # 'Sign out'
37
- link_to(I18n.t(:sign_out, scope: "mod.standard.set.self.account_links"),
38
- card_path("delete/:signin"), id: "signout-link")
28
+ view :invite, perms: ->(r) { r.show_invite_link? },
29
+ denial: :blank do |args|
30
+ link_to args[:link_text], args[:link_opts]
39
31
  end
40
32
 
41
33
  view :my_card, perms: ->(_r) { Auth.signed_in? },
42
34
  denial: :blank do |_args|
43
- card_link(Auth.current.cardname, id: "my-card-link")
35
+ link_to_card Auth.current.cardname, nil, id: "my-card-link"
36
+ end
37
+
38
+ def default_sign_up_args args
39
+ account_link_text :sign_up, args
40
+ account_link_opts "signup-link", args, action: :new, type: :signup
41
+ end
42
+
43
+ def default_sign_in_args args
44
+ account_link_text :sign_in, args
45
+ account_link_opts "signin-link", args
46
+ end
47
+
48
+ def default_invite_args args
49
+ account_link_text :invite, args
50
+ account_link_opts "invite-a-friend-link", args, action: :new, type: :signup
51
+ end
52
+
53
+ def default_sign_out_args args
54
+ account_link_text :sign_out, args
55
+ account_link_opts "signout-link", args, action: :delete
56
+ end
57
+
58
+ def account_link_text purpose, args
59
+ args[:link_text] =
60
+ args.delete(:title) ||
61
+ I18n.t(purpose, scope: "mod.standard.set.self.account_links")
62
+ end
63
+
64
+ def account_link_opts id, args, path=nil
65
+ args[:link_opts] ||= {}
66
+ args[:link_opts][:id] ||= id
67
+ args[:link_opts][:path] ||= path if path
44
68
  end
45
69
 
46
70
  view :raw do |args|
@@ -48,7 +72,8 @@ format :html do
48
72
  end
49
73
 
50
74
  view :core do |args|
51
- content_tag :span, id: "logging" do
75
+ status_class = Auth.signed_in? ? "logged-in" : "logged-out"
76
+ content_tag :span, id: "logging", class: status_class do
52
77
  render_raw args
53
78
  end
54
79
  end
@@ -62,4 +87,3 @@ format :html do
62
87
  Card.new(type_id: Card.default_accounted_type_id).ok?(:create)
63
88
  end
64
89
  end
65
-