ar-extensions 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,3 +1,5 @@
1
+ *ar-extensions is not compatible and is not being developed for Rails 3. Please use the activerecord-import gem which supports the same interface.*
2
+
1
3
  LICENSE
2
4
  ----------
3
5
  This is licensed under the ruby license.
@@ -10,6 +12,11 @@ Email: zach.dennis@gmail.com
10
12
  - For project information and feedback please consult http://rubyforge.org/projects/arext/
11
13
  - For release information please see below
12
14
 
15
+ ActiveRecord::Extensions 0.9.4
16
+ ------------------------------
17
+ April 6, 2011
18
+ - Added :synchronize_keys option for import which allows people to synchronize on specified fields besides the primary key. Note these fields should be unique
19
+
13
20
  ActiveRecord::Extensions 0.9.0, 0.9.1
14
21
  ------------------------------
15
22
  April 17, 2009
@@ -123,6 +123,11 @@ class ActiveRecord::Base
123
123
  # BlogPost.import posts, :synchronize=>[ post ]
124
124
  # puts post.author_name # => 'yoda'
125
125
  #
126
+ # # Example synchronizing unsaved/new instances in memory by using a uniqued imported field
127
+ # posts = [BlogPost.new(:title => "Foo"), BlogPost.new(:title => "Bar")]
128
+ # BlogPost.import posts, :synchronize => posts
129
+ # puts posts.first.new_record? # => false
130
+ #
126
131
  # == On Duplicate Key Update (MySQL only)
127
132
  #
128
133
  # The :on_duplicate_key_update option can be either an Array or a Hash.
@@ -206,8 +211,10 @@ class ActiveRecord::Base
206
211
  num_inserts = import_without_validations_or_callbacks( column_names, array_of_attributes, options )
207
212
  OpenStruct.new :failed_instances=>[], :num_inserts=>num_inserts
208
213
  end
214
+
209
215
  if options[:synchronize]
210
- synchronize( options[:synchronize] )
216
+ sync_keys = options[:synchronize_keys] || [self.primary_key]
217
+ synchronize( options[:synchronize], sync_keys)
211
218
  end
212
219
 
213
220
  return_obj.num_inserts = 0 if return_obj.num_inserts.nil?
@@ -2,28 +2,54 @@ module ActiveRecord # :nodoc:
2
2
  class Base # :nodoc:
3
3
 
4
4
  # Synchronizes the passed in ActiveRecord instances with data
5
- # from the database. This is like calling reload
6
- # on an individual ActiveRecord instance but it is intended for use on
7
- # multiple instances.
8
- #
5
+ # from the database. This is like calling reload on an individual
6
+ # ActiveRecord instance but it is intended for use on multiple instances.
7
+ #
9
8
  # This uses one query for all instance updates and then updates existing
10
9
  # instances rather sending one query for each instance
11
- def self.synchronize(instances, key=self.primary_key)
10
+ #
11
+ # == Examples
12
+ # # Synchronizing existing models (ie: models with an id)
13
+ # posts = Post.find_by_author("Zach")
14
+ # Post.import [:id, :author], [[posts.first.id, "Zachary"]], :synchronize => posts
15
+ # posts.first.author # => "Zachary" instead of Zach
16
+ #
17
+ # # Synchronizing new/unsaved models by using a unique column to perform the sync
18
+ # posts = [Post.new(:author => "Zach")]
19
+ # posts.first.new_record? # => true
20
+ # posts.first.id # => nil
21
+ # Post.import posts, :synchronize => posts
22
+ # posts.first.new_record? # => false
23
+ # posts.first.id # => 1
24
+ #
25
+ def self.synchronize(instances, keys=[self.primary_key])
12
26
  return if instances.empty?
27
+
28
+ conditions = {}
29
+ order = ""
30
+
31
+ key_values = keys.map { |key| instances.map(&"#{key}".to_sym) }
32
+ keys.zip(key_values).each { |key, values| conditions[key] = values }
33
+ order = keys.map{ |key| "#{key} ASC" }.join(",")
13
34
 
14
- keys = instances.map(&"#{key}".to_sym)
15
35
  klass = instances.first.class
16
- fresh_instances = klass.find( :all, :conditions=>{ key=>keys }, :order=>"#{key} ASC" )
17
36
 
18
- instances.each_with_index do |instance, index|
19
- instance.clear_aggregation_cache
20
- instance.clear_association_cache
21
- instance.instance_variable_set '@attributes', fresh_instances[index].attributes
37
+ fresh_instances = klass.find( :all, :conditions=>conditions, :order=>order )
38
+ instances.each do |instance|
39
+ matched_instance = fresh_instances.detect do |fresh_instance|
40
+ keys.all?{ |key| fresh_instance.send(key) == instance.send(key) }
41
+ end
42
+
43
+ if matched_instance
44
+ instance.clear_aggregation_cache
45
+ instance.clear_association_cache
46
+ instance.instance_variable_set '@attributes', matched_instance.attributes
47
+ end
22
48
  end
23
49
  end
24
50
 
25
51
  # See ActiveRecord::ConnectionAdapters::AbstractAdapter.synchronize
26
- def synchronize(instances, key=ActiveRecord::Base.primary_key)
52
+ def synchronize(instances, key=[ActiveRecord::Base.primary_key])
27
53
  self.class.synchronize(instances, key)
28
54
  end
29
55
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar-extensions
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
5
- prerelease: false
4
+ hash: 51
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 3
10
- version: 0.9.3
9
+ - 4
10
+ version: 0.9.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Zach Dennis
@@ -119,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
119
  requirements: []
120
120
 
121
121
  rubyforge_project: arext
122
- rubygems_version: 1.3.7
122
+ rubygems_version: 1.6.0
123
123
  signing_key:
124
124
  specification_version: 3
125
125
  summary: Extends ActiveRecord functionality.