cogniteev-intercom 2.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +6 -0
- data/Gemfile +13 -0
- data/MIT-LICENSE +21 -0
- data/README.md +378 -0
- data/Rakefile +21 -0
- data/changes.txt +168 -0
- data/intercom.gemspec +28 -0
- data/lib/data/cacert.pem +3965 -0
- data/lib/ext/sliceable_hash.rb +16 -0
- data/lib/intercom.rb +176 -0
- data/lib/intercom/admin.rb +9 -0
- data/lib/intercom/api_operations/convert.rb +19 -0
- data/lib/intercom/api_operations/count.rb +16 -0
- data/lib/intercom/api_operations/delete.rb +15 -0
- data/lib/intercom/api_operations/find.rb +23 -0
- data/lib/intercom/api_operations/find_all.rb +33 -0
- data/lib/intercom/api_operations/list.rb +17 -0
- data/lib/intercom/api_operations/load.rb +16 -0
- data/lib/intercom/api_operations/save.rb +51 -0
- data/lib/intercom/collection_proxy.rb +71 -0
- data/lib/intercom/company.rb +29 -0
- data/lib/intercom/contact.rb +22 -0
- data/lib/intercom/conversation.rb +17 -0
- data/lib/intercom/count.rb +21 -0
- data/lib/intercom/errors.rb +61 -0
- data/lib/intercom/event.rb +11 -0
- data/lib/intercom/extended_api_operations/reply.rb +16 -0
- data/lib/intercom/extended_api_operations/tags.rb +14 -0
- data/lib/intercom/extended_api_operations/users.rb +17 -0
- data/lib/intercom/generic_handlers/base_handler.rb +22 -0
- data/lib/intercom/generic_handlers/count.rb +59 -0
- data/lib/intercom/generic_handlers/tag.rb +71 -0
- data/lib/intercom/generic_handlers/tag_find_all.rb +47 -0
- data/lib/intercom/lib/dynamic_accessors.rb +59 -0
- data/lib/intercom/lib/dynamic_accessors_on_method_missing.rb +53 -0
- data/lib/intercom/lib/flat_store.rb +31 -0
- data/lib/intercom/lib/typed_json_deserializer.rb +53 -0
- data/lib/intercom/message.rb +9 -0
- data/lib/intercom/note.rb +17 -0
- data/lib/intercom/notification.rb +20 -0
- data/lib/intercom/request.rb +166 -0
- data/lib/intercom/segment.rb +14 -0
- data/lib/intercom/subscription.rb +15 -0
- data/lib/intercom/tag.rb +23 -0
- data/lib/intercom/traits/api_resource.rb +132 -0
- data/lib/intercom/traits/dirty_tracking.rb +33 -0
- data/lib/intercom/traits/generic_handler_binding.rb +29 -0
- data/lib/intercom/traits/incrementable_attributes.rb +12 -0
- data/lib/intercom/user.rb +30 -0
- data/lib/intercom/utils.rb +62 -0
- data/lib/intercom/version.rb +3 -0
- data/spec/spec_helper.rb +308 -0
- data/spec/unit/intercom/admin_spec.rb +9 -0
- data/spec/unit/intercom/collection_proxy_spec.rb +34 -0
- data/spec/unit/intercom/company_spec.rb +23 -0
- data/spec/unit/intercom/contact_spec.rb +25 -0
- data/spec/unit/intercom/event_spec.rb +25 -0
- data/spec/unit/intercom/lib/flat_store_spec.rb +29 -0
- data/spec/unit/intercom/message_spec.rb +21 -0
- data/spec/unit/intercom/note_spec.rb +19 -0
- data/spec/unit/intercom/notification_spec.rb +68 -0
- data/spec/unit/intercom/request_spec.rb +16 -0
- data/spec/unit/intercom/subscription_spec.rb +18 -0
- data/spec/unit/intercom/tag_spec.rb +23 -0
- data/spec/unit/intercom/traits/api_resource_spec.rb +85 -0
- data/spec/unit/intercom/user_spec.rb +230 -0
- data/spec/unit/intercom_spec.rb +90 -0
- metadata +214 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'intercom/api_operations/count'
|
2
|
+
require 'intercom/api_operations/list'
|
3
|
+
require 'intercom/api_operations/find'
|
4
|
+
require 'intercom/api_operations/find_all'
|
5
|
+
require 'intercom/api_operations/save'
|
6
|
+
require 'intercom/api_operations/load'
|
7
|
+
require 'intercom/extended_api_operations/users'
|
8
|
+
require 'intercom/extended_api_operations/tags'
|
9
|
+
require 'intercom/traits/incrementable_attributes'
|
10
|
+
require 'intercom/traits/api_resource'
|
11
|
+
|
12
|
+
module Intercom
|
13
|
+
class Company
|
14
|
+
include ApiOperations::Count
|
15
|
+
include ApiOperations::List
|
16
|
+
include ApiOperations::Find
|
17
|
+
include ApiOperations::FindAll
|
18
|
+
include ApiOperations::Save
|
19
|
+
include ApiOperations::Load
|
20
|
+
include ExtendedApiOperations::Users
|
21
|
+
include ExtendedApiOperations::Tags
|
22
|
+
include Traits::IncrementableAttributes
|
23
|
+
include Traits::ApiResource
|
24
|
+
|
25
|
+
def identity_vars ; [:id, :company_id] ; end
|
26
|
+
def flat_store_attributes ; [:custom_attributes] ; end
|
27
|
+
def update_verb ; 'post' ; end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'intercom/api_operations/count'
|
2
|
+
require 'intercom/api_operations/load'
|
3
|
+
require 'intercom/api_operations/find'
|
4
|
+
require 'intercom/api_operations/find_all'
|
5
|
+
require 'intercom/api_operations/save'
|
6
|
+
require 'intercom/api_operations/convert'
|
7
|
+
require 'intercom/traits/api_resource'
|
8
|
+
|
9
|
+
module Intercom
|
10
|
+
class Contact
|
11
|
+
include ApiOperations::Load
|
12
|
+
include ApiOperations::Find
|
13
|
+
include ApiOperations::FindAll
|
14
|
+
include ApiOperations::Save
|
15
|
+
include ApiOperations::Convert
|
16
|
+
include Traits::ApiResource
|
17
|
+
|
18
|
+
def identity_vars ; [:email, :user_id] ; end
|
19
|
+
def flat_store_attributes ; [:custom_attributes] ; end
|
20
|
+
def update_verb; 'put' ; end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'intercom/extended_api_operations/reply'
|
2
|
+
require 'intercom/api_operations/find_all'
|
3
|
+
require 'intercom/api_operations/find'
|
4
|
+
require 'intercom/api_operations/load'
|
5
|
+
require 'intercom/api_operations/save'
|
6
|
+
require 'intercom/traits/api_resource'
|
7
|
+
|
8
|
+
module Intercom
|
9
|
+
class Conversation
|
10
|
+
include ExtendedApiOperations::Reply
|
11
|
+
include ApiOperations::FindAll
|
12
|
+
include ApiOperations::Find
|
13
|
+
include ApiOperations::Load
|
14
|
+
include ApiOperations::Save
|
15
|
+
include Traits::ApiResource
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'intercom/traits/api_resource'
|
2
|
+
require 'intercom/api_operations/find'
|
3
|
+
require 'intercom/traits/generic_handler_binding'
|
4
|
+
require 'intercom/generic_handlers/count'
|
5
|
+
|
6
|
+
module Intercom
|
7
|
+
class Count
|
8
|
+
include ApiOperations::Find
|
9
|
+
include Traits::ApiResource
|
10
|
+
include Traits::GenericHandlerBinding
|
11
|
+
include GenericHandlers::Count
|
12
|
+
|
13
|
+
def self.fetch_for_app
|
14
|
+
Intercom::Count.find({})
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.fetch_broken_down_count(entity_to_count, count_context)
|
18
|
+
Intercom::Count.find(:type => entity_to_count, :count => count_context)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Intercom
|
2
|
+
|
3
|
+
# Base class exception from which all public Intercom exceptions will be derived
|
4
|
+
class IntercomError < StandardError
|
5
|
+
attr_reader :http_code, :application_error_code
|
6
|
+
def initialize(message, http_code = nil, error_code = application_error_code)
|
7
|
+
@http_code = http_code
|
8
|
+
@application_error_code = error_code
|
9
|
+
super(message)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Raised when the credentials you provide don't match a valid account on Intercom.
|
14
|
+
# Check that you have set <b>Intercom.app_id=</b> and <b>Intercom.app_api_key=</b> correctly.
|
15
|
+
class AuthenticationError < IntercomError; end
|
16
|
+
|
17
|
+
# Raised when something does wrong on within the Intercom API service.
|
18
|
+
class ServerError < IntercomError; end
|
19
|
+
|
20
|
+
# Raised when we have bad gateway errors.
|
21
|
+
class BadGatewayError < IntercomError; end
|
22
|
+
|
23
|
+
# Raised when we experience a socket read timeout
|
24
|
+
class ServiceUnavailableError < IntercomError; end
|
25
|
+
|
26
|
+
# Raised when we experience socket connect timeout
|
27
|
+
class ServiceConnectionError < IntercomError; end
|
28
|
+
|
29
|
+
# Raised when requesting resources on behalf of a user that doesn't exist in your application on Intercom.
|
30
|
+
class ResourceNotFound < IntercomError; end
|
31
|
+
|
32
|
+
# Raised when the request has a bad syntax
|
33
|
+
class BadRequestError < IntercomError; end
|
34
|
+
|
35
|
+
# Raised when you have exceed the API rate limit
|
36
|
+
class RateLimitExceeded < IntercomError; end
|
37
|
+
|
38
|
+
# Raised when the request throws an error not accounted for
|
39
|
+
class UnexpectedError < IntercomError; end
|
40
|
+
|
41
|
+
# Raised when multiple users match the query (typically duplicate email addresses)
|
42
|
+
class MultipleMatchingUsersError < IntercomError; end
|
43
|
+
|
44
|
+
# Raised when you try to call a non-setter method that does not exist on an object
|
45
|
+
class Intercom::AttributeNotSetError < IntercomError ; end
|
46
|
+
|
47
|
+
# Raised when unexpected nil returned from server
|
48
|
+
class Intercom::HttpError < IntercomError ; end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Non-public errors (internal to the gem)
|
52
|
+
#
|
53
|
+
|
54
|
+
# Base class exception from which all public Intercom exceptions will be derived
|
55
|
+
class IntercomInternalError < StandardError; end
|
56
|
+
|
57
|
+
# Raised when we attempt to handle a method missing but are unsuccessful
|
58
|
+
class Intercom::NoMethodMissingHandler < IntercomInternalError; end
|
59
|
+
|
60
|
+
class Intercom::DeserializationError < IntercomInternalError; end
|
61
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'intercom/api_operations/save'
|
2
|
+
require 'intercom/api_operations/find_all'
|
3
|
+
require 'intercom/traits/api_resource'
|
4
|
+
|
5
|
+
module Intercom
|
6
|
+
class Event
|
7
|
+
include ApiOperations::FindAll
|
8
|
+
include ApiOperations::Save
|
9
|
+
include Traits::ApiResource
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'intercom/traits/api_resource'
|
2
|
+
|
3
|
+
module Intercom
|
4
|
+
module ExtendedApiOperations
|
5
|
+
module Reply
|
6
|
+
|
7
|
+
def reply(reply_data)
|
8
|
+
collection_name = Utils.resource_class_to_collection_name(self.class)
|
9
|
+
# TODO: For server, we should not need to merge in :conversation_id here (already in the URL)
|
10
|
+
response = Intercom.post("/#{collection_name}/#{id}/reply", reply_data.merge(:conversation_id => id))
|
11
|
+
from_response(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'intercom/traits/api_resource'
|
2
|
+
|
3
|
+
module Intercom
|
4
|
+
module ExtendedApiOperations
|
5
|
+
module Tags
|
6
|
+
|
7
|
+
def tags
|
8
|
+
collection_name = Utils.resource_class_to_collection_name(self.class)
|
9
|
+
self.id ? Intercom::Tag.send("find_all_for_#{collection_name}", :id => id) : []
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'intercom/traits/api_resource'
|
2
|
+
|
3
|
+
module Intercom
|
4
|
+
module ExtendedApiOperations
|
5
|
+
module Users
|
6
|
+
|
7
|
+
def users
|
8
|
+
collection_name = Utils.resource_class_to_collection_name(self.class)
|
9
|
+
finder_details = {}
|
10
|
+
finder_details[:url] = "/#{collection_name}/#{id}/users"
|
11
|
+
finder_details[:params] = {}
|
12
|
+
CollectionProxy.new("users", finder_details)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Intercom
|
2
|
+
module GenericHandlers
|
3
|
+
class BaseHandler
|
4
|
+
attr_reader :method_sym, :arguments, :entity
|
5
|
+
|
6
|
+
def initialize(method_sym, arguments, entity)
|
7
|
+
@method_sym = method_sym
|
8
|
+
@arguments = arguments
|
9
|
+
@entity = entity
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_string
|
13
|
+
method_sym.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def raise_no_method_missing_handler
|
17
|
+
raise Intercom::NoMethodMissingHandler, "Could not handle '#{method_string}'"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'intercom/generic_handlers/base_handler'
|
2
|
+
|
3
|
+
module Intercom
|
4
|
+
module GenericHandlers
|
5
|
+
module Count
|
6
|
+
module ClassMethods
|
7
|
+
def generic_count(method_sym, *arguments, &block)
|
8
|
+
|
9
|
+
handler_class = Class.new(GenericHandlers::BaseHandler) do
|
10
|
+
def handle
|
11
|
+
match = method_string.match(GenericHandlers::Count.count_breakdown_matcher)
|
12
|
+
if match && match[1] && match[2] && match[3].nil?
|
13
|
+
do_broken_down_count(match[1], match[2])
|
14
|
+
elsif method_string.end_with? '_count'
|
15
|
+
return do_count
|
16
|
+
else
|
17
|
+
raise_no_method_missing_handler
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def do_count
|
24
|
+
entity.fetch_for_app.send(appwide_entity_to_count)['count']
|
25
|
+
rescue Intercom::AttributeNotSetError
|
26
|
+
# Indicates this this kind of counting is not supported
|
27
|
+
raise_no_method_missing_handler
|
28
|
+
end
|
29
|
+
|
30
|
+
def do_broken_down_count(entity_to_count, count_context)
|
31
|
+
result = entity.fetch_broken_down_count(entity_to_count, count_context)
|
32
|
+
result.send(entity_to_count)[count_context]
|
33
|
+
rescue Intercom::BadRequestError => ex
|
34
|
+
# Indicates this this kind of counting is not supported
|
35
|
+
ex.application_error_code == 'parameter_invalid' ? raise_no_method_missing_handler : raise
|
36
|
+
end
|
37
|
+
|
38
|
+
def appwide_entity_to_count; method_string.gsub(/_count$/, ''); end
|
39
|
+
end
|
40
|
+
|
41
|
+
handler_class.new(method_sym, arguments, self).handle
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.count_breakdown_matcher
|
47
|
+
/([[:alnum:]]+)_counts_for_each_([[:alnum:]]+)/
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.handles_method?(method_sym)
|
51
|
+
method_sym.to_s.end_with? '_count' or method_sym.to_s.match(count_breakdown_matcher)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.included(base)
|
55
|
+
base.extend(ClassMethods)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'intercom/generic_handlers/base_handler'
|
2
|
+
|
3
|
+
module Intercom
|
4
|
+
module GenericHandlers
|
5
|
+
module Tag
|
6
|
+
module ClassMethods
|
7
|
+
def generic_tag(method_sym, *arguments, &block)
|
8
|
+
|
9
|
+
handler_class = Class.new(GenericHandlers::BaseHandler) do
|
10
|
+
def handle
|
11
|
+
if method_string.start_with? 'tag_'
|
12
|
+
return do_tagging
|
13
|
+
elsif method_string.start_with? 'untag_'
|
14
|
+
return do_untagging
|
15
|
+
else
|
16
|
+
raise_no_method_missing_handler
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def do_tagging
|
23
|
+
entity.create(:name => arguments[0], tagging_context.to_sym => tag_object_list(arguments))
|
24
|
+
end
|
25
|
+
|
26
|
+
def do_untagging
|
27
|
+
current_tag = find_tag(arguments[0])
|
28
|
+
return untag_via_save(current_tag) if current_tag
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_tag(name_arg)
|
32
|
+
Intercom::Tag.find(:name => name_arg)
|
33
|
+
rescue Intercom::ResourceNotFound
|
34
|
+
return nil # Ignore if tag has since been deleted
|
35
|
+
end
|
36
|
+
|
37
|
+
def untag_via_save(current_tag)
|
38
|
+
current_tag.name = arguments[0]
|
39
|
+
current_tag.send("#{untagging_context}=", untag_object_list(arguments))
|
40
|
+
current_tag.save
|
41
|
+
end
|
42
|
+
|
43
|
+
def tag_object_list(args)
|
44
|
+
args[1].map { |id| { :id => id } }
|
45
|
+
end
|
46
|
+
|
47
|
+
def untag_object_list(args)
|
48
|
+
to_tag = tag_object_list(args)
|
49
|
+
to_tag.map { |tag_object| tag_object[:untag] = true }
|
50
|
+
to_tag
|
51
|
+
end
|
52
|
+
|
53
|
+
def tagging_context; method_string.gsub(/^tag_/, ''); end
|
54
|
+
def untagging_context; method_string.gsub(/^untag_/, ''); end
|
55
|
+
end
|
56
|
+
|
57
|
+
handler_class.new(method_sym, arguments, self).handle
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.handles_method?(method_sym)
|
63
|
+
method_sym.to_s.start_with?('tag_') || method_sym.to_s.start_with?('untag_')
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.included(base)
|
67
|
+
base.extend(ClassMethods)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'intercom/generic_handlers/base_handler'
|
2
|
+
|
3
|
+
module Intercom
|
4
|
+
module GenericHandlers
|
5
|
+
module TagFindAll
|
6
|
+
module ClassMethods
|
7
|
+
def generic_tag_find_all(method_sym, *arguments, &block)
|
8
|
+
|
9
|
+
handler_class = Class.new(GenericHandlers::BaseHandler) do
|
10
|
+
def handle
|
11
|
+
if method_string.start_with? 'find_all_for_'
|
12
|
+
return do_tag_find_all
|
13
|
+
else
|
14
|
+
raise_no_method_missing_handler
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def do_tag_find_all
|
21
|
+
Intercom::Tag.find_all(cleaned_arguments.merge(:taggable_type => Utils.singularize(context)))
|
22
|
+
end
|
23
|
+
|
24
|
+
def cleaned_arguments
|
25
|
+
cleaned_args = arguments[0]
|
26
|
+
cleaned_args[:taggable_id] = cleaned_args.delete(:id) if cleaned_args.has_key?(:id)
|
27
|
+
cleaned_args
|
28
|
+
end
|
29
|
+
|
30
|
+
def context; method_string.gsub(/^find_all_for_/, ''); end
|
31
|
+
end
|
32
|
+
|
33
|
+
handler_class.new(method_sym, arguments, self).handle
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.handles_method?(method_sym)
|
39
|
+
method_sym.to_s.start_with? 'find_all_for_'
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.included(base)
|
43
|
+
base.extend(ClassMethods)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Intercom
|
2
|
+
module Lib
|
3
|
+
module DynamicAccessors
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def define_accessors(attribute, value, object)
|
8
|
+
klass = object.class
|
9
|
+
if attribute.to_s.end_with?('_at') && attribute.to_s != 'update_last_request_at'
|
10
|
+
define_date_based_accessors(attribute, value, klass)
|
11
|
+
elsif object.flat_store_attribute?(attribute)
|
12
|
+
define_flat_store_based_accessors(attribute, value, klass)
|
13
|
+
else
|
14
|
+
define_standard_accessors(attribute, value, klass)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def define_flat_store_based_accessors(attribute, value, klass)
|
21
|
+
klass.class_eval %Q"
|
22
|
+
def #{attribute}=(value)
|
23
|
+
mark_field_as_changed!(:#{attribute})
|
24
|
+
@#{attribute} = Intercom::Lib::FlatStore.new(value)
|
25
|
+
end
|
26
|
+
def #{attribute}
|
27
|
+
@#{attribute}
|
28
|
+
end
|
29
|
+
"
|
30
|
+
end
|
31
|
+
|
32
|
+
def define_date_based_accessors(attribute, value, klass)
|
33
|
+
klass.class_eval %Q"
|
34
|
+
def #{attribute}=(value)
|
35
|
+
mark_field_as_changed!(:#{attribute})
|
36
|
+
@#{attribute} = value.nil? ? nil : value.to_i
|
37
|
+
end
|
38
|
+
def #{attribute}
|
39
|
+
@#{attribute}.nil? ? nil : Time.at(@#{attribute})
|
40
|
+
end
|
41
|
+
"
|
42
|
+
end
|
43
|
+
|
44
|
+
def define_standard_accessors(attribute, value, klass)
|
45
|
+
klass.class_eval %Q"
|
46
|
+
def #{attribute}=(value)
|
47
|
+
mark_field_as_changed!(:#{attribute})
|
48
|
+
@#{attribute} = value
|
49
|
+
end
|
50
|
+
def #{attribute}
|
51
|
+
@#{attribute}
|
52
|
+
end
|
53
|
+
"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|