Module: Card::Model::SaveHelper

Included in:
Card::Migration
Defined in:
lib/card/model/save_helper.rb

Overview

API to create and update cards. It is intended as a helper for "external" scripts (seeding, testing, migrating, etc) and not for internal application code. The general pattern is: All methods use the ActiveRecord !-methods that throw exceptions if somethings fails. All !-methods in this module rename existing cards to resolve name conflicts)

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object



237
238
239
240
241
242
# File 'lib/card/model/save_helper.rb', line 237

def method_missing method, *args
  method_name, cardtype_card = extract_cardtype_from_method_name method
  return super unless method_name
  args = standardize_args(*args)
  send "#{method_name}_card", args.merge(type_id: cardtype_card.id)
end

Instance Method Details

#add_coderule_item(name, prefix, type_id, to) ⇒ Object



217
218
219
220
221
222
223
224
# File 'lib/card/model/save_helper.rb', line 217

def add_coderule_item name, prefix, type_id, to
  codename = "#{prefix}_#{name.tr(' ', '_').underscore}"
  name = "#{prefix}: #{name}"

  ensure_card name, type_id: type_id,
              codename: codename
  Card[to].add_item! name
end

#add_name(name, content_or_args) ⇒ Object



167
168
169
170
171
172
173
# File 'lib/card/model/save_helper.rb', line 167

def add_name name, content_or_args
  if content_or_args.is_a?(String)
    { content: content_or_args, name: name }
  else
    content_or_args.reverse_merge name: name
  end
end

#add_script(name, opts = {}) ⇒ Object



207
208
209
210
211
212
213
214
# File 'lib/card/model/save_helper.rb', line 207

def add_script name, opts={}
  name.sub!(/^script\:?\s?/, '') # in case name is given with prefix
  # remove it so that we don't double it

  add_coderule_item name, "script",
                    opts[:type_id] || Card::CoffeeScriptID,
                    opts[:to] || "*all+*script"
end

#add_style(name, opts = {}) ⇒ Object



198
199
200
201
202
203
204
205
# File 'lib/card/model/save_helper.rb', line 198

def add_style name, opts={}
  name.sub!(/^style\:?\s?/, '') # in case name is given with prefix
  # remove it so that we don't double it

  add_coderule_item name, "style",
                    opts[:type_id] || Card::ScssID,
                    opts[:to] || "*all+*style"
end

#create_args(name_or_args, content_or_args = nil) ⇒ Object



157
158
159
160
161
# File 'lib/card/model/save_helper.rb', line 157

def create_args name_or_args, content_or_args=nil
  args = standardize_args name_or_args, content_or_args
  resolve_name_conflict args
  args
end

#create_card(name_or_args, content_or_args = nil) ⇒ Object Also known as: create



18
19
20
# File 'lib/card/model/save_helper.rb', line 18

def create_card name_or_args, content_or_args=nil
  Card.create! create_args(name_or_args, content_or_args)
end

#create_card!(name_or_args, content_or_args = nil) ⇒ Object Also known as: create!

if card with same name exists move it out of the way



124
125
126
127
# File 'lib/card/model/save_helper.rb', line 124

def create_card! name_or_args, content_or_args=nil
  args = standardize_args name_or_args, content_or_args
  create_card args.reverse_merge(rename_if_conflict: :old)
end

#create_or_update_card(name_or_args, content_or_args = nil) ⇒ Object Also known as: create_or_update



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/card/model/save_helper.rb', line 28

def create_or_update_card name_or_args, content_or_args=nil
  name = name_from_args name_or_args

  if Card[name]
    args = standardize_update_args name_or_args, content_or_args
    update_card(name, args)
  else
    args = standardize_args name_or_args, content_or_args
    create_card(args)
  end
end

#create_or_update_card!(name_or_args, content_or_args = nil) ⇒ Object Also known as: create_or_update!



134
135
136
137
# File 'lib/card/model/save_helper.rb', line 134

def create_or_update_card! name_or_args, content_or_args=nil
  args = standardize_args name_or_args, content_or_args
  create_or_update args.reverse_merge(rename_if_conflict: :new)
end

#delete_card(name) ⇒ Object Also known as: delete



40
41
42
43
# File 'lib/card/model/save_helper.rb', line 40

def delete_card name
  return unless Card.exist?(name)
  Card[name].delete!
end

#delete_code_card(name) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/card/model/save_helper.rb', line 45

def delete_code_card name
  if name.is_a? Symbol
    return unless Card::Codename.exist? name
  end
  return unless Card.exist?(name)
  update_card name, codename: nil
  delete_card name
end

#ensure_attributes(card, args) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/card/model/save_helper.rb', line 181

def ensure_attributes card, args
  # args = args.to_h.with_indifferent_access
  subcards = card.extract_subcard_args! args
  update_args =
    args.select do |key, value|
      if key =~ /^\+/
        subfields[key] = value
        false
      else
        card.send(key) != value
      end
    end
  return if update_args.empty? && subcards.empty?
  # FIXME: use ensure_attributes for subcards
  card.update_attributes! update_args.merge(subcards: subcards)
end

#ensure_card(name_or_args, content_or_args = nil) ⇒ Object Also known as: ensure

create if card doesn't exist updates existing card only if given attributes are different except the name

Examples:

if a card with name "under_score" exists

ensure_card "Under Score"                 # => no change
ensure_card "Under Score", type: :pointer # => changes the type to pointer
                                          #    but not the name


61
62
63
64
65
66
67
68
69
70
# File 'lib/card/model/save_helper.rb', line 61

def ensure_card name_or_args, content_or_args=nil
  args = standardize_args name_or_args, content_or_args
  name = args.delete(:name)
  if (card = Card[name])
    ensure_attributes card, args
    card
  else
    Card.create! args.merge(name: name)
  end
end

#ensure_card!(name_or_args, content_or_args = nil) ⇒ Object Also known as: ensure!

create if card doesn't exist updates existing card only if given attributes are different including the name For example if a card with name "under_score" exists then ensure_card "Under Score" renames it to "Under Score"



77
78
79
80
81
82
83
84
# File 'lib/card/model/save_helper.rb', line 77

def ensure_card! name_or_args, content_or_args=nil
  args = standardize_args name_or_args, content_or_args
  if (card = Card[args[:name]])
    ensure_attributes card, args
  else
    Card.create! args
  end
end

#ensure_trait(name, codename, args = {}) ⇒ Object

Creates or updates a trait card with codename and right rules. Content for rules that are pointer cards by default is converted to pointer format.

Examples:

ensure_trait "*a_or_b", :a_or_b,
             default: { type_id: Card::PointerID },
             options: ["A", "B"],
             input: "radio"


95
96
97
98
99
100
# File 'lib/card/model/save_helper.rb', line 95

def ensure_trait name, codename, args={}
  ensure_card name, codename: codename
  args.each do |setting, value|
    ensure_trait_rule name, setting, value
  end
end

#ensure_trait_rule(trait, setting, value) ⇒ Object



102
103
104
105
106
# File 'lib/card/model/save_helper.rb', line 102

def ensure_trait_rule trait, setting, value
  validate_setting setting
  card_args = normalize_trait_rule_args setting, value
  ensure_card [trait, :right, setting], card_args
end

#extract_cardtype_from_method_name(method) ⇒ Object



248
249
250
251
252
253
254
255
# File 'lib/card/model/save_helper.rb', line 248

def extract_cardtype_from_method_name method
  return unless method =~ /^(?<method_name>create|ensure)_(?<type>.+)(?:_card)?$/
  cardtype_card = Card[Regexp.last_match[:type]] ||
                  Card[Regexp.last_match[:type].to_sym]
  return unless cardtype_card&.type_id == Card::CardtypeID ||
                cardtype_card.id == Card::SetID
  [Regexp.last_match[:method_name], cardtype_card]
end

#name_from_args(name_or_args) ⇒ Object



163
164
165
# File 'lib/card/model/save_helper.rb', line 163

def name_from_args name_or_args
  name_or_args.is_a?(Hash) ? name_or_args[:name] : name_or_args
end

#normalize_trait_rule_args(setting, value) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/card/model/save_helper.rb', line 115

def normalize_trait_rule_args setting, value
  return value if value.is_a? Hash
  if Card.fetch_type_id([setting, :right, :default]) == PointerID
    value = Array(value).to_pointer_content
  end
  { content: value }
end

#resolve_name_conflict(args) ⇒ Object



175
176
177
178
179
# File 'lib/card/model/save_helper.rb', line 175

def resolve_name_conflict args
  rename = args.delete :rename_if_conflict
  return unless args[:name] && rename
  args[:name] = Card.uniquify_name args[:name], rename
end

#respond_to_missing?(method, _include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


244
245
246
# File 'lib/card/model/save_helper.rb', line 244

def respond_to_missing? method, _include_private=false
  extract_cardtype_from_method_name(method) || super
end

#standardize_args(name_or_args, content_or_args = nil) ⇒ Object

Returns args.

Returns:

  • args



140
141
142
143
144
145
146
# File 'lib/card/model/save_helper.rb', line 140

def standardize_args name_or_args, content_or_args=nil
  if name_or_args.is_a?(Hash)
    name_or_args
  else
    add_name name_or_args, content_or_args || {}
  end
end

#standardize_update_args(name_or_args, content_or_args) ⇒ Object



148
149
150
151
152
153
154
155
# File 'lib/card/model/save_helper.rb', line 148

def standardize_update_args name_or_args, content_or_args
  return name_or_args if name_or_args.is_a?(Hash)
  if content_or_args.is_a?(String)
    { content: content_or_args }
  else
    content_or_args
  end
end

#update_card(name, content_or_args) ⇒ Object Also known as: update



22
23
24
25
26
# File 'lib/card/model/save_helper.rb', line 22

def update_card name, content_or_args
  args = standardize_update_args name, content_or_args
  resolve_name_conflict args
  Card[name].update_attributes! args
end

#update_card!(name, content_or_args) ⇒ Object Also known as: update!



129
130
131
132
# File 'lib/card/model/save_helper.rb', line 129

def update_card! name, content_or_args
  args = standardize_update_args name, content_or_args
  update_card name, args.reverse_merge(rename_if_conflict: :new)
end

#validate_setting(setting) ⇒ Object



108
109
110
111
112
113
# File 'lib/card/model/save_helper.rb', line 108

def validate_setting setting
  unless Card::Codename.exist?(setting) &&
         Card.fetch_type_id(setting) == SettingID
    raise ArgumentError, "not a valid setting: #{setting}"
  end
end

#with_user(user_name) ⇒ Object



12
13
14
15
16
# File 'lib/card/model/save_helper.rb', line 12

def with_user user_name
  Card::Auth.with current_id: Card.fetch_id(user_name) do
    yield
  end
end