sugarcrm 0.9.6 → 0.9.7

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.6
1
+ 0.9.7
@@ -2,7 +2,6 @@ module SugarCRM
2
2
  # A class for handling association collections. Basically just an extension of Array
3
3
  # doesn't actually load the records from Sugar until you invoke one of the public methods
4
4
  class AssociationCollection
5
- include Enumerable
6
5
 
7
6
  # creates a new instance of an AssociationCollection
8
7
  # Owner is the parent object, and association is the target
@@ -32,18 +31,7 @@ module SugarCRM
32
31
  def reload
33
32
  load_associated_records
34
33
  end
35
-
36
- def each(&block)
37
- load
38
- @collection.each(&block)
39
- end
40
-
41
- # we should probably delegate this
42
- def length
43
- load
44
- @collection.length
45
- end
46
-
34
+
47
35
  # return any added elements
48
36
  def added
49
37
  load
@@ -83,6 +71,13 @@ module SugarCRM
83
71
  end
84
72
  alias :add :<<
85
73
 
74
+ # delegate undefined methods to the @collection array
75
+ # E.g. contact.cases should behave like an array and allow `length`, `size`, `each`, etc.
76
+ def method_missing(method_name, *args, &block)
77
+ load
78
+ @collection.send(method_name.to_sym, *args, &block)
79
+ end
80
+
86
81
  def save
87
82
  begin
88
83
  save!
@@ -123,14 +118,7 @@ module SugarCRM
123
118
  # user would be the owner, and EmailAddress.new() is the target
124
119
  def associate!(target, opts={})
125
120
  #target.save! if target.new?
126
- response = SugarCRM.connection.set_relationship(
127
- @owner.class._module.name, @owner.id,
128
- target.class._module.table_name, [target.id],
129
- opts
130
- )
131
- raise AssociationFailed,
132
- "Couldn't associate #{@owner.class._module.name}: #{@owner.id} -> #{target.class._module.table_name}:#{target.id}!" if response["failed"] > 0
133
- true
121
+ @owner.associate!(target, [target.id], opts)
134
122
  end
135
123
 
136
124
  # Removes a relationship between the current object and the target
@@ -20,6 +20,30 @@ module SugarCRM; module AssociationMethods
20
20
  false
21
21
  end
22
22
 
23
+ # Creates a relationship between the current object and the target
24
+ # The current instance and target records will have a relationship set
25
+ # i.e. account.associate!(contact) wyould link account and contact
26
+ # In contrast to using account.contacts << contact, this method doesn't load the relationships
27
+ # before setting the new relationship.
28
+ # This method is useful when certain modules have many links to other modules: not loading the
29
+ # relationships allows one ot avoid a Timeout::Error
30
+ def associate!(target, target_ids=[], opts={})
31
+ if self.class._module.custom_module? || target.class._module.custom_module?
32
+ link_field = get_link_field(target)
33
+ else
34
+ link_field = target.class._module.table_name
35
+ end
36
+ target_ids = [target.id] if target_ids.size < 1
37
+ response = SugarCRM.connection.set_relationship(
38
+ self.class._module.name, self.id,
39
+ link_field, target_ids,
40
+ opts
41
+ )
42
+ raise AssociationFailed,
43
+ "Couldn't associate #{self.class._module.name}: #{self.id} -> #{target.class._module.table_name}:#{target.id}!" if response["failed"] > 0
44
+ true
45
+ end
46
+
23
47
  protected
24
48
 
25
49
  def save_modified_associations
@@ -70,5 +94,15 @@ module SugarCRM; module AssociationMethods
70
94
  @association_cache[association] = collection
71
95
  collection
72
96
  end
97
+
98
+ # return the link field involving a relationship with a custom module
99
+ def get_link_field(other)
100
+ this_table_name = self.class._module.custom_module? ? self.class._module.name : self.class._module.table_name
101
+ that_table_name = other.class._module.custom_module? ? other.class._module.name : other.class._module.table_name
102
+ # the link field will contain the name of both modules
103
+ link_field = self.associations.detect{|a| a == [this_table_name, that_table_name].join('_') || a == [that_table_name, this_table_name].join('_')}
104
+ raise "Unable to determine link field between #{self.class._module.name}: #{self.id} and #{other.class._module.table_name}:#{other.id}" unless link_field
105
+ link_field
106
+ end
73
107
 
74
108
  end; end
data/lib/sugarcrm/base.rb CHANGED
@@ -41,12 +41,7 @@ module SugarCRM; class Base
41
41
  when :first
42
42
  find_initial(options)
43
43
  when :all
44
- results = find_every(options)
45
- if results
46
- Array.wrap(results)
47
- else
48
- []
49
- end
44
+ Array.wrap(find_every(options)).compact
50
45
  else
51
46
  find_from_ids(args, options)
52
47
  end
@@ -158,7 +153,7 @@ module SugarCRM; class Base
158
153
 
159
154
  def find_by_sql(options)
160
155
  query = query_from_options(options)
161
- SugarCRM.connection.get_entry_list(self._module.name, query, options)
156
+ SugarCRM.connection.get_entry_list(self._module.name, query, options) || nil # return nil instead of false if no results are found
162
157
  end
163
158
 
164
159
  def query_from_options(options)
@@ -342,6 +337,18 @@ module SugarCRM; class Base
342
337
  end
343
338
  alias :eql? :==
344
339
 
340
+ def update_attribute(name, value)
341
+ self.send("#{name}=".to_sym, value)
342
+ self.save
343
+ end
344
+
345
+ def update_attributes(attributes)
346
+ attributes.each do |name, value|
347
+ self.send("#{name}=".to_sym, value)
348
+ end
349
+ self.save
350
+ end
351
+
345
352
  # Delegates to id in order to allow two records of the same type and id to work with something like:
346
353
  # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
347
354
  def hash
@@ -20,7 +20,7 @@ module SugarCRM
20
20
  # custom attributes are contained in a table named after the module, with a '_cstm' suffix
21
21
  # the module's table name must be tableized for the modules that ship with SugarCRM
22
22
  # for custom modules (created in the Studio), table name don't need to be tableized: the name passed to the constructor is already tableized
23
- unless name.downcase == name # this module is a custom module (custom module names are all lower_case, whereas SugarCRM modules are CamelCase
23
+ unless self.custom_module?
24
24
  @custom_table_name = @table_name + "_cstm"
25
25
  else
26
26
  @custom_table_name = name + "_cstm"
@@ -32,6 +32,12 @@ module SugarCRM
32
32
  self
33
33
  end
34
34
 
35
+ # return true if this module was created in the SugarCRM Studio (i.e. it is not part of the modules that
36
+ # ship in the dfault SugarCRM configuration
37
+ def custom_module?
38
+ name.downcase == name # custom module names are all lower_case, whereas SugarCRM modules are CamelCase
39
+ end
40
+
35
41
  # Returns the fields associated with the module
36
42
  def fields
37
43
  return @fields if fields_registered?
@@ -4,6 +4,8 @@ class TestAssociations < Test::Unit::TestCase
4
4
  context "A SugarCRM::Base instance" do
5
5
  should "return an email address when sent #email_addresses" do
6
6
  u = SugarCRM::User.find("seed_sarah_id")
7
+ assert_instance_of SugarCRM::AssociationCollection, u.email_addresses
8
+ assert_instance_of SugarCRM::EmailAddress, u.email_addresses.first
7
9
  assert_equal "sarah@example.com", u.email_addresses.first.email_address
8
10
  end
9
11
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sugarcrm
3
3
  version: !ruby/object:Gem::Version
4
- hash: 55
4
+ hash: 53
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 6
10
- version: 0.9.6
9
+ - 7
10
+ version: 0.9.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Carl Hicks
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-11 00:00:00 -08:00
18
+ date: 2011-01-15 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency