mavenlink 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/README.md +241 -0
- data/Rakefile +28 -0
- data/bin/mavenlink-console +18 -0
- data/doc/ml_logo_lb-primary.png +0 -0
- data/lib/config/specification.yml +1665 -0
- data/lib/mavenlink.rb +134 -0
- data/lib/mavenlink/account_invitation.rb +4 -0
- data/lib/mavenlink/account_membership.rb +4 -0
- data/lib/mavenlink/additional_item.rb +4 -0
- data/lib/mavenlink/assignment.rb +5 -0
- data/lib/mavenlink/attachment.rb +11 -0
- data/lib/mavenlink/backup_approver_association.rb +4 -0
- data/lib/mavenlink/client.rb +116 -0
- data/lib/mavenlink/concerns/custom_fieldable.rb +9 -0
- data/lib/mavenlink/concerns/indestructible.rb +11 -0
- data/lib/mavenlink/concerns/locked_record.rb +30 -0
- data/lib/mavenlink/cost_rate.rb +4 -0
- data/lib/mavenlink/custom_field.rb +4 -0
- data/lib/mavenlink/custom_field_choice.rb +5 -0
- data/lib/mavenlink/custom_field_value.rb +4 -0
- data/lib/mavenlink/errors.rb +47 -0
- data/lib/mavenlink/expense.rb +4 -0
- data/lib/mavenlink/expense_category.rb +4 -0
- data/lib/mavenlink/expense_report_submission.rb +7 -0
- data/lib/mavenlink/external_payment.rb +4 -0
- data/lib/mavenlink/external_reference.rb +24 -0
- data/lib/mavenlink/fixed_fee_item.rb +4 -0
- data/lib/mavenlink/holiday.rb +4 -0
- data/lib/mavenlink/holiday_calendar.rb +4 -0
- data/lib/mavenlink/holiday_calendar_association.rb +4 -0
- data/lib/mavenlink/holiday_calendar_membership.rb +4 -0
- data/lib/mavenlink/invoice.rb +4 -0
- data/lib/mavenlink/logger.rb +62 -0
- data/lib/mavenlink/model.rb +279 -0
- data/lib/mavenlink/organization.rb +4 -0
- data/lib/mavenlink/organization_membership.rb +4 -0
- data/lib/mavenlink/participation.rb +4 -0
- data/lib/mavenlink/post.rb +4 -0
- data/lib/mavenlink/project_template.rb +4 -0
- data/lib/mavenlink/project_template_assignment.rb +4 -0
- data/lib/mavenlink/railtie.rb +7 -0
- data/lib/mavenlink/rate_card.rb +4 -0
- data/lib/mavenlink/rate_card_role.rb +4 -0
- data/lib/mavenlink/rate_card_set.rb +4 -0
- data/lib/mavenlink/rate_card_set_version.rb +30 -0
- data/lib/mavenlink/rate_card_version.rb +4 -0
- data/lib/mavenlink/request.rb +241 -0
- data/lib/mavenlink/resolution.rb +4 -0
- data/lib/mavenlink/response.rb +22 -0
- data/lib/mavenlink/role.rb +5 -0
- data/lib/mavenlink/settings.rb +11 -0
- data/lib/mavenlink/skill.rb +4 -0
- data/lib/mavenlink/skill_category.rb +4 -0
- data/lib/mavenlink/skill_membership.rb +4 -0
- data/lib/mavenlink/specificators/association.rb +13 -0
- data/lib/mavenlink/specificators/attribute.rb +13 -0
- data/lib/mavenlink/specificators/base.rb +24 -0
- data/lib/mavenlink/specificators/validation.rb +27 -0
- data/lib/mavenlink/status_report.rb +4 -0
- data/lib/mavenlink/story.rb +8 -0
- data/lib/mavenlink/story_allocation_day.rb +5 -0
- data/lib/mavenlink/story_dependency.rb +5 -0
- data/lib/mavenlink/story_task.rb +5 -0
- data/lib/mavenlink/tag.rb +5 -0
- data/lib/mavenlink/time_adjustment.rb +4 -0
- data/lib/mavenlink/time_entry.rb +4 -0
- data/lib/mavenlink/time_off_entry.rb +4 -0
- data/lib/mavenlink/timesheet_submission.rb +4 -0
- data/lib/mavenlink/user.rb +5 -0
- data/lib/mavenlink/vendor.rb +4 -0
- data/lib/mavenlink/workspace.rb +21 -0
- data/lib/mavenlink/workspace_group.rb +5 -0
- data/lib/mavenlink/workspace_invoice_preference.rb +4 -0
- data/lib/mavenlink/workweek.rb +4 -0
- data/lib/mavenlink/workweek_membership.rb +4 -0
- data/mavenlink.gemspec +29 -0
- data/spec/lib/mavenlink/account_membership_spec.rb +8 -0
- data/spec/lib/mavenlink/assignment_spec.rb +17 -0
- data/spec/lib/mavenlink/attachment_spec.rb +30 -0
- data/spec/lib/mavenlink/backup_approver_association_spec.rb +9 -0
- data/spec/lib/mavenlink/client_spec.rb +187 -0
- data/spec/lib/mavenlink/concerns/indestructible_spec.rb +13 -0
- data/spec/lib/mavenlink/concerns/locked_record_spec.rb +28 -0
- data/spec/lib/mavenlink/cost_rate_spec.rb +9 -0
- data/spec/lib/mavenlink/custom_field_value_spec.rb +10 -0
- data/spec/lib/mavenlink/expense_report_submission_spec.rb +16 -0
- data/spec/lib/mavenlink/expense_spec.rb +23 -0
- data/spec/lib/mavenlink/external_references_spec.rb +144 -0
- data/spec/lib/mavenlink/holiday_calendar_association_spec.rb +8 -0
- data/spec/lib/mavenlink/holiday_calendar_membership_spec.rb +8 -0
- data/spec/lib/mavenlink/holiday_spec.rb +7 -0
- data/spec/lib/mavenlink/invalid_request_error_spec.rb +9 -0
- data/spec/lib/mavenlink/invoice_spec.rb +176 -0
- data/spec/lib/mavenlink/model_spec.rb +439 -0
- data/spec/lib/mavenlink/post_spec.rb +23 -0
- data/spec/lib/mavenlink/rate_card_set_version_spec.rb +119 -0
- data/spec/lib/mavenlink/record_invalid_error_spec.rb +16 -0
- data/spec/lib/mavenlink/record_not_found_error_spec.rb +9 -0
- data/spec/lib/mavenlink/request_spec.rb +381 -0
- data/spec/lib/mavenlink/response_spec.rb +50 -0
- data/spec/lib/mavenlink/role_spec.rb +9 -0
- data/spec/lib/mavenlink/settings_spec.rb +23 -0
- data/spec/lib/mavenlink/skill_category_spec.rb +7 -0
- data/spec/lib/mavenlink/skill_membership_spec.rb +9 -0
- data/spec/lib/mavenlink/skill_spec.rb +8 -0
- data/spec/lib/mavenlink/specificators/association_spec.rb +25 -0
- data/spec/lib/mavenlink/specificators/attribute_spec.rb +25 -0
- data/spec/lib/mavenlink/specificators/validation_spec.rb +39 -0
- data/spec/lib/mavenlink/story_allocation_day_spec.rb +64 -0
- data/spec/lib/mavenlink/story_dependency_spec.rb +16 -0
- data/spec/lib/mavenlink/story_spec.rb +69 -0
- data/spec/lib/mavenlink/time_adjustment_spec.rb +13 -0
- data/spec/lib/mavenlink/time_entry_spec.rb +43 -0
- data/spec/lib/mavenlink/time_off_entry_spec.rb +9 -0
- data/spec/lib/mavenlink/user_spec.rb +138 -0
- data/spec/lib/mavenlink/workspace_group_spec.rb +25 -0
- data/spec/lib/mavenlink/workspace_spec.rb +431 -0
- data/spec/lib/mavenlink_spec.rb +43 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/shared_examples.rb +148 -0
- metadata +267 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Mavenlink
|
|
2
|
+
class ExternalReference < Model
|
|
3
|
+
def save
|
|
4
|
+
if valid?
|
|
5
|
+
reload(create_or_update(attributes_for_create_or_update))
|
|
6
|
+
true
|
|
7
|
+
else
|
|
8
|
+
false
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def create_or_update(attributes)
|
|
15
|
+
request.perform do
|
|
16
|
+
client.post("external_references/create_or_update", { external_reference: attributes})
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def attributes_for_create_or_update
|
|
21
|
+
specification_attributes("create_or_update_attributes")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Mavenlink
|
|
2
|
+
class Logger < ::Logger
|
|
3
|
+
# @todo(SZ) YARD, docu, describe colors, when to use each one
|
|
4
|
+
|
|
5
|
+
# @param device [nil, STDOUT, STDERR]
|
|
6
|
+
def initialize(device)
|
|
7
|
+
super
|
|
8
|
+
self.level = Logger::FATAL
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @param [String] message
|
|
12
|
+
def disappointment(message)
|
|
13
|
+
info("\e[#{35}m[Maven]\e[0m \e[#{31}m#{message}\e[0m") if error?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @param [String] message
|
|
17
|
+
def hint(message)
|
|
18
|
+
info("\e[#{32}m[Maven]\e[1m \e[#{33}m#{message}\e[0m") if warn?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @param [String] message
|
|
22
|
+
def note(message)
|
|
23
|
+
info("\e[#{32}m[Maven]\e[0m \e[#{36}m#{message}\e[0m") if info?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @param [String] message
|
|
27
|
+
def whisper(message)
|
|
28
|
+
info("\e[#{32}m[Maven]\e[0m \e[#{37}m#{message}\e[0m") if debug?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param [String] message
|
|
32
|
+
def inspection(message)
|
|
33
|
+
if debug?
|
|
34
|
+
if message.respond_to?(:awesome_inspect)
|
|
35
|
+
info(message.awesome_inspect)
|
|
36
|
+
else
|
|
37
|
+
info(message.inspect)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @param [String] message
|
|
43
|
+
def self.disappointment(message)
|
|
44
|
+
Mavenlink.logger.disappointment(message)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @param [String] message
|
|
48
|
+
def self.hint(message)
|
|
49
|
+
Mavenlink.logger.hint(message)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @param [String] message
|
|
53
|
+
def self.note(message)
|
|
54
|
+
Mavenlink.logger.note(message)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @param [String] message
|
|
58
|
+
def self.whisper(message)
|
|
59
|
+
Mavenlink.logger.whisper(message)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
module Mavenlink
|
|
2
|
+
class Model < BrainstemAdaptor::Record
|
|
3
|
+
include ActiveModel::Validations
|
|
4
|
+
|
|
5
|
+
attr_reader :client
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
delegate :only, :find, :search, :filter, :page, :total_count, :per_page, :limit, :offset, :order, :all, to: :scoped
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @return [String]
|
|
12
|
+
def self.collection_name
|
|
13
|
+
(self.name || 'undefined').split(/\W+/).last.tableize.pluralize
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @param attributes [Hash]
|
|
17
|
+
# @return [Mavenlink::Model]
|
|
18
|
+
def self.create(attributes = {})
|
|
19
|
+
self.new(attributes).tap(&:save)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @raise [Mavenlink::RecordInvalidError]
|
|
23
|
+
# @param attributes [Hash]
|
|
24
|
+
# @return [Mavenlink::Model]
|
|
25
|
+
def self.create!(attributes = {})
|
|
26
|
+
create(attributes).tap do |record|
|
|
27
|
+
record.valid? or raise RecordInvalidError.new(record)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @return [Mavenlink::Request]
|
|
32
|
+
def self.includes(*args)
|
|
33
|
+
scoped.include(*args)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @param client [Mavenlink::Client]
|
|
37
|
+
# @return [Mavenlink::Request]
|
|
38
|
+
def self.scoped(client = Mavenlink.client)
|
|
39
|
+
Mavenlink::Request.new(collection_name, client)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @return [Mavenlink::Request]
|
|
43
|
+
def scoped_im
|
|
44
|
+
Mavenlink::Request.new(collection_name, client)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @param model_class [Mavenlink::Model]
|
|
48
|
+
def self.inherited(model_class)
|
|
49
|
+
::Mavenlink::Model.models[model_class.collection_name] = model_class
|
|
50
|
+
|
|
51
|
+
# Applies specification file to the model
|
|
52
|
+
Mavenlink::Specificators::Attribute.apply(model_class)
|
|
53
|
+
Mavenlink::Specificators::Association.apply(model_class)
|
|
54
|
+
Mavenlink::Specificators::Validation.apply(model_class)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Returns all models registered in the app
|
|
58
|
+
# @return [Hash<String, Class>] key is collection name and value is a model assigned to this collection
|
|
59
|
+
def self.models
|
|
60
|
+
@models ||= ActiveSupport::HashWithIndifferentAccess.new
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Returns collection specification
|
|
64
|
+
# @return [Hash]
|
|
65
|
+
def self.specification
|
|
66
|
+
@specification ||= Mavenlink.specification[collection_name] || {}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @todo REFACTOR NA
|
|
70
|
+
# @param association_name [String, Symbol]
|
|
71
|
+
def self.association(association_name)
|
|
72
|
+
define_method association_name do |reload = false|
|
|
73
|
+
return nil if new_record?
|
|
74
|
+
|
|
75
|
+
association = association_by_name(association_name)
|
|
76
|
+
reload = true unless association.loaded?
|
|
77
|
+
|
|
78
|
+
if reload
|
|
79
|
+
reload_association(association)
|
|
80
|
+
associations_cache[association_name] = fetch_association_records(association)
|
|
81
|
+
elsif associations_cache.has_key?(association_name)
|
|
82
|
+
associations_cache[association_name]
|
|
83
|
+
else
|
|
84
|
+
associations_cache[association_name] = fetch_association_records(association)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# @param names [String, Symbol]
|
|
90
|
+
def self.attribute(*names)
|
|
91
|
+
names.each do |name|
|
|
92
|
+
define_method(name) { self[name.to_s] }
|
|
93
|
+
define_method("#{name}=") { |value| self[name.to_s] = value }
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Returns list of available attributes
|
|
98
|
+
# @return [Array<String>]
|
|
99
|
+
def self.attributes
|
|
100
|
+
specification['attributes'] ||= []
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Returns list of all available attributes
|
|
104
|
+
# @return [Array<String>]
|
|
105
|
+
def self.available_attributes
|
|
106
|
+
create_attributes | update_attributes | attributes
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Returns the list of attributes available for new record
|
|
110
|
+
# @return [Array<String>]
|
|
111
|
+
def self.create_attributes
|
|
112
|
+
specification['create_attributes'] ||= []
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Returns the list of attributes available for update
|
|
116
|
+
# @return [Array<String>]
|
|
117
|
+
def self.update_attributes
|
|
118
|
+
specification['update_attributes'] ||= []
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# @param source_record [Brainstem::Record, nil]
|
|
122
|
+
# @param client [Mavenlink::Client]
|
|
123
|
+
def self.wrap(source_record = nil, client = Mavenlink.client)
|
|
124
|
+
self.new({}, source_record, client)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# @param attributes [Hash]
|
|
128
|
+
# @param source_record [BrainstemAdaptor::Record]
|
|
129
|
+
# @param client [Mavenlink::Client]
|
|
130
|
+
def initialize(attributes = {}, source_record = nil, client = Mavenlink.client)
|
|
131
|
+
super(self.class.collection_name, (attributes[:id] || attributes['id'] || source_record.try(:id)), source_record.try(:response))
|
|
132
|
+
@client = client
|
|
133
|
+
merge!(attributes)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# @param attributes [Hash]
|
|
137
|
+
def attributes=(attributes)
|
|
138
|
+
merge!(attributes)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def persisted?
|
|
142
|
+
!!id
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def new_record?
|
|
146
|
+
!persisted?
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# @return [true, false]
|
|
150
|
+
def save
|
|
151
|
+
if valid?
|
|
152
|
+
reload(new_record? ? create : update)
|
|
153
|
+
true
|
|
154
|
+
else
|
|
155
|
+
false
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# @raise [Mavenlink::RecordInvalidError]
|
|
160
|
+
# @return [true]
|
|
161
|
+
def save!
|
|
162
|
+
save or raise Mavenlink::RecordInvalidError.new(self)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# @param attributes [Hash]
|
|
166
|
+
# @return [true, false]
|
|
167
|
+
def update_attributes(attributes)
|
|
168
|
+
self.attributes = attributes
|
|
169
|
+
save
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# @param attributes [Hash]
|
|
173
|
+
# @raise [Mavenlink::RecordInvalidError]
|
|
174
|
+
# @return [true]
|
|
175
|
+
def update_attributes!(attributes)
|
|
176
|
+
self.attributes = attributes
|
|
177
|
+
save!
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# @note does not work, don't know what to do with removed record.
|
|
181
|
+
# will just return RecordNotFound error if you call #save after #destroy
|
|
182
|
+
def destroy
|
|
183
|
+
request.delete
|
|
184
|
+
end
|
|
185
|
+
alias_method :delete, :destroy
|
|
186
|
+
|
|
187
|
+
# Reloads record from server
|
|
188
|
+
# @return [self]
|
|
189
|
+
def reload(response = nil)
|
|
190
|
+
response ||= request.find(id).try(:response) or raise RecordNotFoundError.new(request)
|
|
191
|
+
@id ||= response.results.first.try(:[], 'id')
|
|
192
|
+
load_fields_with(response)
|
|
193
|
+
self
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @overload
|
|
197
|
+
# @param context [:create, :update]
|
|
198
|
+
# @return [true, false]
|
|
199
|
+
def valid?(context = saving_context)
|
|
200
|
+
Mavenlink::Settings[:default][:perform_validations] ? super(context.try(:to_sym)) : true
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# @return [String, nil]
|
|
204
|
+
def to_param
|
|
205
|
+
id.try(:to_s)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
protected
|
|
209
|
+
|
|
210
|
+
# @return [Mavenlink::Response]
|
|
211
|
+
def create
|
|
212
|
+
request.create(attributes_for_create)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# @return [Mavenlink::Response]
|
|
216
|
+
def update
|
|
217
|
+
request.update(attributes_for_update)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# @return [Hash]
|
|
221
|
+
def attributes_for_create
|
|
222
|
+
specification_attributes('create_attributes')
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# @return [Hash]
|
|
226
|
+
def attributes_for_update
|
|
227
|
+
specification_attributes('update_attributes')
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# @return [Mavenlink::Request]
|
|
231
|
+
def request
|
|
232
|
+
collection_scope.only(id)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
private
|
|
236
|
+
|
|
237
|
+
# Stores requested data in a Hash
|
|
238
|
+
# @return [Hash]
|
|
239
|
+
def associations_cache
|
|
240
|
+
@associations_cache ||= {}.with_indifferent_access
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# @return [Mavenlink::Request]
|
|
244
|
+
def collection_scope
|
|
245
|
+
@collection_scope ||= self.class.scoped(client)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# @param association [BrainstemAdaptor::Association]
|
|
249
|
+
# @return [Array<Mavenlink::Model>, nil]
|
|
250
|
+
def fetch_association_records(association)
|
|
251
|
+
records = association.reflect
|
|
252
|
+
|
|
253
|
+
if records
|
|
254
|
+
wrapper = proc { |record| Mavenlink::Model.models[association.collection_name].wrap(record, client) }
|
|
255
|
+
records.kind_of?(BrainstemAdaptor::Association) ? records.map(&wrapper) : wrapper.call(records, client)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# @param association [BrainstemAdaptor::Association]
|
|
260
|
+
def reload_association(association)
|
|
261
|
+
response = request.include(association.name).find(id).try(:response) or raise RecordNotFoundError.new(request)
|
|
262
|
+
load_fields_with(response, [association.foreign_key])
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def saving_context
|
|
266
|
+
new_record? ? :create : :update
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# @param key [String]
|
|
270
|
+
# @return [Hash]
|
|
271
|
+
def specification_attributes(key)
|
|
272
|
+
{}.tap do |result|
|
|
273
|
+
self.to_hash.slice(*self.class.specification[key]).each do |attr_name, value|
|
|
274
|
+
result[attr_name] = value
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|