card 1.17.1 → 1.17.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/config/initializers/recaptcha.rb +27 -19
- data/db/migrate/20160122153608_new_indeces.rb +10 -0
- data/db/migrate_core_cards/20130411191151_renaming_for_menu.rb +2 -2
- data/db/migrate_core_cards/20140317035504_account_requests_to_signups.rb +2 -2
- data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +2 -2
- data/db/migrate_core_cards/20150807205221_create_references_for_search_cards.rb +4 -2
- data/db/schema.rb +5 -1
- data/db/version.txt +1 -1
- data/lib/card.rb +3 -3
- data/lib/card/reference.rb +68 -52
- data/mod/01_core/chunk/query_reference.rb +1 -1
- data/mod/01_core/set/all/collection.rb +1 -1
- data/mod/01_core/set/all/name.rb +27 -65
- data/mod/01_core/set/all/pattern.rb +6 -3
- data/mod/01_core/set/all/references.rb +135 -62
- data/mod/01_core/set/all/tracked_attributes.rb +1 -1
- data/mod/01_core/set/all/utils.rb +2 -2
- data/mod/01_core/spec/set/all/references_spec.rb +4 -3
- data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +16 -22
- data/mod/01_history/lib/card/act.rb +32 -30
- data/mod/01_history/lib/card/change.rb +26 -18
- data/mod/01_history/set/all/history.rb +1 -1
- data/mod/04_settings/set/right/structure.rb +1 -1
- data/mod/05_email/set/all/notify.rb +1 -1
- data/mod/05_email/spec/set/right/followers_spec.rb +1 -1
- data/mod/05_standard/set/all/rich_html/editing.rb +42 -45
- data/mod/05_standard/set/type/list.rb +2 -2
- data/mod/05_standard/spec/set/self/all_spec.rb +3 -3
- data/mod/05_standard/spec/set/type/list_spec.rb +3 -3
- data/mod/05_standard/spec/set/type/listed_by_spec.rb +2 -2
- data/mod/05_standard/spec/set/type/search_type_spec.rb +1 -1
- data/spec/lib/card/reference_spec.rb +30 -28
- data/spec/models/card/trash_spec.rb +63 -63
- data/spec/models/card/type_transition_spec.rb +34 -35
- metadata +3 -2
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
def patterns
|
3
|
-
@patterns ||= set_patterns.map { |sub| sub.new
|
3
|
+
@patterns ||= set_patterns.map { |sub| sub.new self }.compact
|
4
4
|
end
|
5
5
|
|
6
6
|
def patterns_with_new
|
@@ -9,7 +9,10 @@ end
|
|
9
9
|
alias_method_chain :patterns, :new
|
10
10
|
|
11
11
|
def reset_patterns
|
12
|
-
@
|
12
|
+
@patterns = nil
|
13
|
+
@template = @virtual = nil
|
14
|
+
@set_mods_loaded = @set_modules = @set_names = @rule_set_keys = nil
|
15
|
+
@junction_only = nil # only applies to set cards
|
13
16
|
true
|
14
17
|
end
|
15
18
|
|
@@ -45,7 +48,7 @@ end
|
|
45
48
|
|
46
49
|
def set_names
|
47
50
|
if @set_names.nil?
|
48
|
-
@set_names = patterns.map
|
51
|
+
@set_names = patterns.map(&:to_s)
|
49
52
|
Card.set_members @set_names, key
|
50
53
|
end
|
51
54
|
@set_names
|
@@ -1,99 +1,172 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
|
3
|
+
# Cards can refer to other cards in their content, eg via links and nests.
|
4
|
+
# The card that refers is the "referer", the card that is referred to is
|
5
|
+
# the "referee". The reference itself has its own class (Card::Reference),
|
6
|
+
# which handles id-based reference tracking.
|
3
7
|
|
4
|
-
|
5
|
-
|
6
|
-
|
8
|
+
PARTIAL_REF_CODE = 'P'.freeze
|
9
|
+
|
10
|
+
# cards that refer to self
|
11
|
+
def referers
|
12
|
+
references_in.map(&:referer_id).map(&Card.method(:fetch)).compact
|
13
|
+
end
|
14
|
+
|
15
|
+
# cards that include self
|
16
|
+
def includers
|
17
|
+
refs = references_in.where(ref_type: 'I')
|
18
|
+
refs.map(&:referer_id).map(&Card.method(:fetch)).compact
|
19
|
+
end
|
20
|
+
|
21
|
+
# cards that self refers to
|
22
|
+
def referees
|
23
|
+
references_out.map { |ref| Card.fetch ref.referee_key, new: {} }
|
7
24
|
end
|
8
25
|
|
9
|
-
|
10
|
-
|
11
|
-
|
26
|
+
# cards that self includes
|
27
|
+
def includees
|
28
|
+
refs = references_out.where(ref_type: 'I')
|
29
|
+
refs.map { |ref| Card.fetch ref.referee_key, new: {} }
|
30
|
+
end
|
31
|
+
|
32
|
+
# cards that refer to self by name
|
33
|
+
# (finds cards not yet linked by id)
|
34
|
+
def name_referers
|
35
|
+
Card.joins(:references_out).where card_references: { referee_key: key }
|
36
|
+
end
|
37
|
+
|
38
|
+
# cards that refer to self or any descendant
|
39
|
+
def family_referers
|
40
|
+
@family_referers ||= ([self] + descendants).map(&:referers).flatten.uniq
|
41
|
+
# FIXME: could be much more efficient!
|
12
42
|
end
|
13
43
|
|
14
44
|
# replace references in card content
|
15
|
-
def
|
45
|
+
def replace_reference_syntax old_name, new_name
|
16
46
|
obj_content = Card::Content.new raw_content, self
|
17
47
|
obj_content.find_chunks(Card::Chunk::Reference).select do |chunk|
|
18
48
|
next unless (old_ref_name = chunk.referee_name)
|
19
49
|
next unless (new_ref_name = old_ref_name.replace_part old_name, new_name)
|
20
50
|
chunk.referee_name = chunk.replace_reference old_name, new_name
|
21
|
-
|
22
|
-
|
51
|
+
refs = Card::Reference.where referee_key: old_ref_name.key
|
52
|
+
refs.update_all referee_key: new_ref_name.key
|
23
53
|
end
|
24
54
|
|
25
55
|
obj_content.to_s
|
26
56
|
end
|
27
57
|
|
28
|
-
#
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
Card::Reference.delete_all_from self unless self.new_card?
|
33
|
-
|
34
|
-
rendered_content ||= Card::Content.new raw_content, self
|
35
|
-
rendered_content.find_chunks(Card::Chunk::Reference).each do |chunk|
|
36
|
-
create_reference_to chunk
|
37
|
-
end
|
58
|
+
# delete old references from this card's content, create new ones
|
59
|
+
def update_references_out
|
60
|
+
delete_references_out
|
61
|
+
create_references_out
|
38
62
|
end
|
39
63
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
# reference types:
|
48
|
-
# L = link
|
49
|
-
# I = inclusion
|
50
|
-
# P = partial (i.e. the name is part of a compound name that is
|
51
|
-
# referenced by a link or inclusion)
|
52
|
-
|
53
|
-
# The partial type is needed to keep track of references of virtual cards.
|
54
|
-
# For example a link [[A+*self]] won't make it to the reference table
|
55
|
-
# because A+*self is virtual and doesn't have an id but when A's name is
|
56
|
-
# changed we have to find and update that link.
|
57
|
-
ref_type = name != referee_name ? PARTIAL_REF_CODE : chunk.reference_code
|
58
|
-
Card::Reference.create!(
|
59
|
-
referer_id: id,
|
60
|
-
referee_id: Card.fetch_id(name),
|
61
|
-
referee_key: name.key,
|
62
|
-
ref_type: ref_type,
|
63
|
-
present: 1
|
64
|
-
)
|
64
|
+
# interpret references from this card's content and
|
65
|
+
# insert entries in reference table
|
66
|
+
def create_references_out
|
67
|
+
ref_hash = {}
|
68
|
+
content_obj = Card::Content.new raw_content, self
|
69
|
+
content_obj.find_chunks(Card::Chunk::Reference).each do |chunk|
|
70
|
+
interpret_reference ref_hash, chunk.referee_name, chunk.reference_code
|
65
71
|
end
|
72
|
+
return if ref_hash.empty?
|
73
|
+
Card::Reference.mass_insert reference_values_array(ref_hash)
|
66
74
|
end
|
67
75
|
|
68
|
-
|
69
|
-
|
76
|
+
# delete references from this card
|
77
|
+
def delete_references_out
|
78
|
+
fail 'id required to delete references' if id.nil?
|
79
|
+
Card::Reference.delete_all referer_id: id
|
70
80
|
end
|
71
81
|
|
72
|
-
|
73
|
-
|
74
|
-
|
82
|
+
# interpretation phase helps to prevent duplicate references
|
83
|
+
# results in hash like:
|
84
|
+
# { referee1_key: [referee1_id, referee1_type1, referee1_type2],
|
85
|
+
# referee2_key...
|
86
|
+
# }
|
87
|
+
def interpret_reference ref_hash, referee_name, ref_type
|
88
|
+
return unless referee_name # eg commented nest has no referee_name
|
89
|
+
referee_key = (referee_name = referee_name.to_name).key
|
90
|
+
return if referee_key == key # don't create self reference
|
91
|
+
|
92
|
+
referee_id = Card.fetch_id(referee_name)
|
93
|
+
ref_hash[referee_key] ||= [referee_id]
|
94
|
+
ref_hash[referee_key] << ref_type
|
95
|
+
|
96
|
+
interpret_partial_references ref_hash, referee_name unless referee_id
|
75
97
|
end
|
76
98
|
|
77
|
-
|
78
|
-
|
99
|
+
# Partial references are needed to track references to virtual cards.
|
100
|
+
# For example a link to virual card [[A+*self]] won't have a referee_id,
|
101
|
+
# but when A's name is changed we have to find and update that link.
|
102
|
+
def interpret_partial_references ref_hash, referee_name
|
103
|
+
[referee_name.left, referee_name.right].each do |sidename|
|
104
|
+
interpret_reference ref_hash, sidename, PARTIAL_REF_CODE
|
105
|
+
end
|
79
106
|
end
|
80
107
|
|
81
|
-
|
82
|
-
|
83
|
-
|
108
|
+
# translate interpreted reference hash into values array,
|
109
|
+
# removing duplicate and unnecessary ref_types
|
110
|
+
def reference_values_array ref_hash
|
111
|
+
values = []
|
112
|
+
ref_hash.each do |referee_key, hash_val|
|
113
|
+
referee_id = hash_val.shift || 'null'
|
114
|
+
ref_types = hash_val.uniq
|
115
|
+
ref_types.delete PARTIAL_REF_CODE if ref_types.size > 1
|
116
|
+
# partial references are not necessary if there are explicit references
|
117
|
+
ref_types.each do |ref_type|
|
118
|
+
values << [id, referee_id, "'#{referee_key}'", "'#{ref_type}'"]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
values
|
84
122
|
end
|
85
123
|
|
86
124
|
protected
|
87
125
|
|
88
|
-
|
89
|
-
|
126
|
+
# test for updating referer content & preload referer list
|
127
|
+
event :prepare_referer_update, before: :approve, on: :update, changed: :name do
|
128
|
+
self.update_referers = ![nil, false, 'false'].member?(update_referers)
|
129
|
+
family_referers
|
90
130
|
end
|
91
131
|
|
92
|
-
|
93
|
-
|
94
|
-
|
132
|
+
# when name changes, update references to card
|
133
|
+
event :refresh_references_in, after: :store, on: :save, changed: :name do
|
134
|
+
Card::Reference.unmap_referees id if @action == :update && !update_referers
|
135
|
+
Card::Reference.map_referees key, id
|
136
|
+
end
|
137
|
+
|
138
|
+
# when content changes, update references to other cards
|
139
|
+
event :refresh_references_out, after: :store, on: :save, changed: :content do
|
140
|
+
update_references_out
|
141
|
+
end
|
142
|
+
|
143
|
+
# clean up reference table when card is deleted
|
144
|
+
event :clear_references, after: :store, on: :delete do
|
145
|
+
delete_references_out
|
146
|
+
Card::Reference.unmap_referees id
|
147
|
+
end
|
148
|
+
|
149
|
+
# on rename, update names in cards that refer to self by name (as directed)
|
150
|
+
event :update_referer_content,
|
151
|
+
after: :store, on: :update, changed: :name,
|
152
|
+
when: proc { |c| c.update_referers } do
|
153
|
+
# FIXME: break into correct stages
|
154
|
+
Auth.as_bot do
|
155
|
+
family_referers.each do |card|
|
156
|
+
next if card == self || card.structure
|
157
|
+
card = card.refresh
|
158
|
+
card.db_content = card.replace_reference_syntax name_was, name
|
159
|
+
card.save!
|
160
|
+
end
|
161
|
+
end
|
95
162
|
end
|
96
163
|
|
97
|
-
|
98
|
-
|
164
|
+
# on rename, when NOT updating referer content, update references to ensure
|
165
|
+
# that partial references are correctly tracked
|
166
|
+
# eg. A links to X+Y. if X+Y is renamed and we're not updating the link in A,
|
167
|
+
# then we need to be sure that A has a partial reference
|
168
|
+
event :update_referer_references_out,
|
169
|
+
after: :store, on: :update, changed: :name,
|
170
|
+
when: proc { |c| !c.update_referers } do
|
171
|
+
family_referers.map(&:update_references_out)
|
99
172
|
end
|
@@ -141,5 +141,5 @@ end
|
|
141
141
|
event :expire_related_names, before: :expire_related, changed: :name do
|
142
142
|
# FIXME: look for opportunities to avoid instantiating the following
|
143
143
|
descendants.each { |c| c.expire(true) }
|
144
|
-
|
144
|
+
name_referers.each { |c| c.expire(true) }
|
145
145
|
end
|
@@ -4,8 +4,8 @@ module ClassMethods
|
|
4
4
|
Card.delete_trashed_files
|
5
5
|
Card.where(trash: true).delete_all
|
6
6
|
Card::Action.delete_cardless
|
7
|
-
Card::Reference.
|
8
|
-
Card::Reference.
|
7
|
+
Card::Reference.unmap_if_referee_missing
|
8
|
+
Card::Reference.delete_if_referer_missing
|
9
9
|
Card.delete_tmp_files_of_cached_uploads
|
10
10
|
end
|
11
11
|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
3
|
describe Card::Set::All::References do
|
4
|
-
it
|
5
|
-
card = Card.create!
|
6
|
-
assert_equal
|
4
|
+
it 'should replace references should work on inclusions inside links' do
|
5
|
+
card = Card.create! name: 'ref test', content: '[[test_card|test{{test}}]]'
|
6
|
+
assert_equal '[[test_card|test{{best}}]]',
|
7
|
+
card.replace_reference_syntax('test', 'best')
|
7
8
|
end
|
8
9
|
end
|
@@ -6,7 +6,7 @@ module RenameMethods
|
|
6
6
|
content: card.content,
|
7
7
|
# updater_id: card.updater_id,
|
8
8
|
# revisions: card.actions.count,
|
9
|
-
|
9
|
+
referers: card.referers.map(&:name).sort,
|
10
10
|
referees: card.referees.map(&:name).sort,
|
11
11
|
descendants: card.descendants.map(&:id).sort
|
12
12
|
}
|
@@ -16,7 +16,7 @@ module RenameMethods
|
|
16
16
|
attrs_before = name_invariant_attributes(card)
|
17
17
|
actions_count_before = card.actions.count
|
18
18
|
card.name = new_name
|
19
|
-
card.
|
19
|
+
card.update_referers = true
|
20
20
|
card.save!
|
21
21
|
expect(card.actions.count).to eq(actions_count_before + 1)
|
22
22
|
assert_equal attrs_before, name_invariant_attributes(card)
|
@@ -119,13 +119,13 @@ describe Card::Set::All::TrackedAttributes do
|
|
119
119
|
c = Card['Menu']
|
120
120
|
c.name = 'manure'
|
121
121
|
c.save!
|
122
|
-
expect(Card['manure'].
|
122
|
+
expect(Card['manure'].references_in.size).to eq(0)
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'picks up new references' do
|
126
126
|
Card.create name: 'kinds of poop', content: '[[manure]]'
|
127
127
|
assert_rename Card['Menu'], 'manure'
|
128
|
-
expect(Card['manure'].
|
128
|
+
expect(Card['manure'].references_in.size).to eq(2)
|
129
129
|
end
|
130
130
|
|
131
131
|
it 'handles name variants' do
|
@@ -155,15 +155,9 @@ describe Card::Set::All::TrackedAttributes do
|
|
155
155
|
end
|
156
156
|
|
157
157
|
it 'test_update_descendants' do
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
Card['Four+One'],
|
162
|
-
Card['Four+One+Five']
|
163
|
-
]
|
164
|
-
|
165
|
-
old_names = %w{ One+Two One+Two+Three Four+One Four+One+Five }
|
166
|
-
new_names = %w{ Uno+Two Uno+Two+Three Four+Uno Four+Uno+Five }
|
158
|
+
old_names = %w( One+Two One+Two+Three Four+One Four+One+Five )
|
159
|
+
new_names = %w( Uno+Two Uno+Two+Three Four+Uno Four+Uno+Five )
|
160
|
+
card_list = old_names.map { |name| Card[name] }
|
167
161
|
|
168
162
|
assert_equal old_names, card_list.map(&:name)
|
169
163
|
Card['One'].update_attributes! name: 'Uno'
|
@@ -193,24 +187,24 @@ describe Card::Set::All::TrackedAttributes do
|
|
193
187
|
expect(Card['Banana Card']).not_to be_nil
|
194
188
|
end
|
195
189
|
|
196
|
-
it '
|
190
|
+
it 'test_rename_should_not_fail_when_updating_inaccessible_referer' do
|
197
191
|
Card.create! name: 'Joe Card', content: 'Whattup'
|
198
192
|
Card::Auth.as 'joe_admin' do
|
199
193
|
Card.create! name: 'Admin Card', content: '[[Joe Card]]'
|
200
194
|
end
|
201
195
|
c = Card['Joe Card']
|
202
|
-
c.update_attributes! name: 'Card of Joe',
|
196
|
+
c.update_attributes! name: 'Card of Joe', update_referers: true
|
203
197
|
assert_equal '[[Card of Joe]]', Card['Admin Card'].content
|
204
198
|
end
|
205
199
|
|
206
|
-
it '
|
200
|
+
it 'test_rename_should_update_structured_referer' do
|
207
201
|
Card::Auth.as_bot do
|
208
202
|
c = Card.create! name: 'Pit'
|
209
203
|
Card.create! name: 'Orange', type: 'Fruit', content: '[[Pit]]'
|
210
204
|
Card.create! name: 'Fruit+*type+*structure', content: 'this [[Pit]]'
|
211
205
|
|
212
206
|
assert_equal 'this [[Pit]]', Card['Orange'].raw_content
|
213
|
-
c.update_attributes! name: 'Seed',
|
207
|
+
c.update_attributes! name: 'Seed', update_referers: true
|
214
208
|
assert_equal 'this [[Seed]]', Card['Orange'].raw_content
|
215
209
|
end
|
216
210
|
end
|
@@ -260,14 +254,14 @@ describe Card::Set::All::TrackedAttributes do
|
|
260
254
|
it 'test_renaming_card_with_self_link_should_not_hang' do
|
261
255
|
c = Card['Dairy']
|
262
256
|
c.name = 'Buttah'
|
263
|
-
c.
|
257
|
+
c.update_referers = true
|
264
258
|
c.save!
|
265
259
|
assert_equal '[[/new/{{_self|name}}|new]]', Card['Buttah'].content
|
266
260
|
end
|
267
261
|
|
268
262
|
it 'should rename card without updating references' do
|
269
263
|
c = Card['Dairy']
|
270
|
-
c.update_attributes name: 'Newt',
|
264
|
+
c.update_attributes name: 'Newt', update_referers: false
|
271
265
|
assert_equal '[[/new/{{_self|name}}|new]]', Card['Newt'].content
|
272
266
|
end
|
273
267
|
end
|
@@ -291,7 +285,7 @@ describe Card::Set::All::TrackedAttributes do
|
|
291
285
|
c1 = Card['Blue']
|
292
286
|
c2 = Card['blue includer 1']
|
293
287
|
c3 = Card['blue includer 2']
|
294
|
-
c1.update_attributes name: 'Red',
|
288
|
+
c1.update_attributes name: 'Red', update_referers: true
|
295
289
|
assert_equal '{{Red}}', Card.find(c2.id).content
|
296
290
|
# NOTE these attrs pass through a hash stage that may not preserve order
|
297
291
|
assert_equal '{{Red|closed;other:stuff}}', Card.find(c3.id).content
|
@@ -301,7 +295,7 @@ describe Card::Set::All::TrackedAttributes do
|
|
301
295
|
c1 = Card['Blue']
|
302
296
|
c2 = Card['blue includer 1']
|
303
297
|
c1.update_attributes name: 'blue includer 1+color',
|
304
|
-
|
298
|
+
update_referers: true
|
305
299
|
assert_equal '{{blue includer 1+color}}', Card.find(c2.id).content
|
306
300
|
end
|
307
301
|
|
@@ -310,7 +304,7 @@ describe Card::Set::All::TrackedAttributes do
|
|
310
304
|
c2 = Card['blue linker 1']
|
311
305
|
c3 = Card['blue linker 2']
|
312
306
|
c1.reload.name = 'Red'
|
313
|
-
c1.
|
307
|
+
c1.update_referers = true
|
314
308
|
c1.save!
|
315
309
|
assert_equal '[[Red]]', Card.find(c2.id).content
|
316
310
|
assert_equal '[[Red]]', Card.find(c3.id).content
|
@@ -2,39 +2,39 @@
|
|
2
2
|
class Card
|
3
3
|
class Act < ActiveRecord::Base
|
4
4
|
before_save :set_actor
|
5
|
-
has_many :actions,
|
6
|
-
|
5
|
+
has_many :actions,
|
6
|
+
-> { order :id },
|
7
|
+
foreign_key: :card_act_id,
|
8
|
+
inverse_of: :act,
|
9
|
+
class_name: 'Card::Action'
|
7
10
|
|
8
|
-
belongs_to :actor, class_name:
|
11
|
+
belongs_to :actor, class_name: 'Card'
|
9
12
|
belongs_to :card
|
10
|
-
def set_actor
|
11
|
-
self.actor_id ||= Auth.current_id
|
12
|
-
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
class << self
|
15
|
+
def delete_actionless
|
16
|
+
joins(
|
17
|
+
'LEFT JOIN card_actions '\
|
18
|
+
'ON card_acts.id = card_actions.card_act_id'
|
19
|
+
).where(
|
20
|
+
'card_actions.id is null'
|
21
|
+
).delete_all
|
22
|
+
end
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def find_all_with_actions_on card_ids, args={}
|
25
|
+
sql = 'card_actions.card_id IN (:card_ids) AND ( (draft is not true) '
|
26
|
+
sql << (args[:with_drafts] ? 'OR actor_id = :current_user_id)' : ')')
|
27
|
+
vars = { card_ids: card_ids, current_user_id: Card::Auth.current_id }
|
28
|
+
joins(:actions).where(sql, vars).uniq.order(:id).reverse_order
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# def card
|
33
|
-
# Card[ card_id ]
|
34
|
-
# end
|
32
|
+
def set_actor
|
33
|
+
self.actor_id ||= Auth.current_id
|
34
|
+
end
|
35
35
|
|
36
36
|
def action_on card_id
|
37
|
-
actions.where(
|
37
|
+
actions.where("card_id = #{card_id} and draft is not true").first
|
38
38
|
end
|
39
39
|
|
40
40
|
def main_action
|
@@ -47,20 +47,22 @@ class Card
|
|
47
47
|
|
48
48
|
def relevant_drafts_for card
|
49
49
|
drafts.select do |action|
|
50
|
-
card.included_card_ids.include?(action.card_id) ||
|
50
|
+
card.included_card_ids.include?(action.card_id) ||
|
51
|
+
(card.id == action.card_id)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
|
-
def relevant_actions_for card
|
55
|
+
def relevant_actions_for card
|
55
56
|
actions.select do |action|
|
56
|
-
card.included_card_ids.include?(action.card_id) ||
|
57
|
+
card.included_card_ids.include?(action.card_id) ||
|
58
|
+
(card.id == action.card_id)
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
60
|
-
|
62
|
+
private
|
63
|
+
|
61
64
|
def timestamp_attributes_for_create
|
62
65
|
super << :acted_at
|
63
66
|
end
|
64
|
-
|
65
67
|
end
|
66
68
|
end
|