tenacity 0.2.0 → 0.3.0
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/.gitignore +3 -0
- data/EXTEND.rdoc +11 -1
- data/README.rdoc +4 -1
- data/Rakefile +20 -9
- data/history.txt +21 -0
- data/lib/tenacity.rb +12 -4
- data/lib/tenacity/associates_proxy.rb +67 -0
- data/lib/tenacity/association.rb +19 -6
- data/lib/tenacity/associations/has_many.rb +6 -0
- data/lib/tenacity/class_methods.rb +52 -1
- data/lib/tenacity/instance_methods.rb +7 -3
- data/lib/tenacity/orm_ext/activerecord.rb +30 -13
- data/lib/tenacity/orm_ext/couchrest.rb +140 -0
- data/lib/tenacity/orm_ext/datamapper.rb +139 -0
- data/lib/tenacity/orm_ext/mongo_mapper.rb +88 -80
- data/lib/tenacity/orm_ext/mongoid.rb +108 -0
- data/lib/tenacity/orm_ext/sequel.rb +134 -0
- data/lib/tenacity/version.rb +1 -1
- data/tenacity.gemspec +14 -3
- data/test/association_features/belongs_to_test.rb +42 -0
- data/test/association_features/has_many_test.rb +110 -0
- data/test/association_features/has_one_test.rb +41 -0
- data/test/associations/belongs_to_test.rb +36 -127
- data/test/associations/has_many_test.rb +77 -196
- data/test/associations/has_one_test.rb +22 -84
- data/test/core/classmethods_test.rb +24 -22
- data/test/fixtures/active_record_has_many_target.rb +10 -0
- data/test/fixtures/active_record_has_one_target.rb +10 -0
- data/test/fixtures/{active_record_nuts.rb → active_record_nut.rb} +0 -0
- data/test/fixtures/active_record_object.rb +17 -0
- data/test/fixtures/couch_rest_door.rb +0 -2
- data/test/fixtures/couch_rest_has_many_target.rb +12 -0
- data/test/fixtures/couch_rest_has_one_target.rb +12 -0
- data/test/fixtures/couch_rest_object.rb +19 -0
- data/test/fixtures/couch_rest_windshield.rb +0 -2
- data/test/fixtures/data_mapper_has_many_target.rb +19 -0
- data/test/fixtures/data_mapper_has_one_target.rb +19 -0
- data/test/fixtures/data_mapper_object.rb +20 -0
- data/test/fixtures/mongo_mapper_ash_tray.rb +0 -2
- data/test/fixtures/mongo_mapper_dashboard.rb +0 -2
- data/test/fixtures/mongo_mapper_has_many_target.rb +11 -0
- data/test/fixtures/mongo_mapper_has_one_target.rb +11 -0
- data/test/fixtures/mongo_mapper_object.rb +18 -0
- data/test/fixtures/mongo_mapper_vent.rb +0 -2
- data/test/fixtures/mongo_mapper_wheel.rb +0 -2
- data/test/fixtures/mongoid_has_many_target.rb +13 -0
- data/test/fixtures/mongoid_has_one_target.rb +13 -0
- data/test/fixtures/mongoid_object.rb +20 -0
- data/test/fixtures/sequel_has_many_target.rb +10 -0
- data/test/fixtures/sequel_has_one_target.rb +10 -0
- data/test/fixtures/sequel_object.rb +17 -0
- data/test/helpers/active_record_test_helper.rb +51 -0
- data/test/helpers/data_mapper_test_helper.rb +44 -0
- data/test/helpers/mongoid_test_helper.rb +21 -0
- data/test/helpers/sequel_test_helper.rb +60 -0
- data/test/orm_ext/activerecord_test.rb +55 -35
- data/test/orm_ext/couchrest_test.rb +66 -46
- data/test/orm_ext/datamapper_test.rb +112 -0
- data/test/orm_ext/mongo_mapper_test.rb +64 -44
- data/test/orm_ext/mongoid_test.rb +121 -0
- data/test/orm_ext/sequel_test.rb +113 -0
- data/test/test_helper.rb +87 -11
- metadata +159 -59
- data/lib/tenacity/orm_ext/couchrest/couchrest_extended_document.rb +0 -42
- data/lib/tenacity/orm_ext/couchrest/couchrest_model.rb +0 -44
- data/lib/tenacity/orm_ext/couchrest/tenacity_class_methods.rb +0 -43
- data/lib/tenacity/orm_ext/couchrest/tenacity_instance_methods.rb +0 -21
- data/test/fixtures/couch_rest_radio.rb +0 -10
- data/test/fixtures/mongo_mapper_button.rb +0 -6
data/.gitignore
CHANGED
data/EXTEND.rdoc
CHANGED
@@ -30,7 +30,8 @@ return nil.
|
|
30
30
|
_t_find_bulk(ids=[])
|
31
31
|
|
32
32
|
Find many objects by the specified ids, and return them in an array.
|
33
|
-
If no objects could be found, return an empty array.
|
33
|
+
If no objects could be found, return an empty array. If only some of
|
34
|
+
the objects could be found, then simply return those objects in the array.
|
34
35
|
|
35
36
|
_t_find_first_by_associate(property, id)
|
36
37
|
|
@@ -41,6 +42,15 @@ and return it. If no object could be found, return nil.
|
|
41
42
|
|
42
43
|
Find all objects by the specified property name, with the specified id, and
|
43
44
|
return them in an array. If no objects could be found, return an empty array.
|
45
|
+
If only some of the objects could be found, then simply return those objects
|
46
|
+
in the array.
|
47
|
+
|
48
|
+
_t_delete(ids, run_callbacks=true)
|
49
|
+
|
50
|
+
Delete all objects with the specified ids. If <tt>run_callbacks</tt> is true, the
|
51
|
+
objects should be deleted in such a way that their delete callback methods
|
52
|
+
are run. If false, the objects should be deleted in such a way that their
|
53
|
+
delete callback meethods are not run. Return nothing.
|
44
54
|
|
45
55
|
_t_initialize_has_many_association(association)
|
46
56
|
|
data/README.rdoc
CHANGED
@@ -83,8 +83,11 @@ much the same way, supporting many of the same options.
|
|
83
83
|
== Supported Database Clients
|
84
84
|
|
85
85
|
* ActiveRecord
|
86
|
-
* MongoMapper
|
87
86
|
* CouchRest (CouchModel and ExtendedDocument)
|
87
|
+
* DataMapper
|
88
|
+
* MongoMapper
|
89
|
+
* Mongoid
|
90
|
+
* Sequel
|
88
91
|
|
89
92
|
See EXTEND.rdoc for information on extending Tenacity to work with other database clients.
|
90
93
|
|
data/Rakefile
CHANGED
@@ -10,16 +10,21 @@ rescue Bundler::BundlerError => e
|
|
10
10
|
$stderr.puts "Run `bundle install` to install missing gems"
|
11
11
|
exit e.status_code
|
12
12
|
end
|
13
|
-
require 'rake'
|
14
13
|
|
14
|
+
require 'rake'
|
15
15
|
require 'rake/testtask'
|
16
|
+
require 'rcov/rcovtask'
|
17
|
+
require 'rake/rdoctask'
|
18
|
+
require 'yard'
|
19
|
+
|
20
|
+
task :default => :test
|
21
|
+
|
16
22
|
Rake::TestTask.new(:test) do |test|
|
17
23
|
test.libs << 'lib' << 'test' << 'test/fixtures'
|
18
|
-
test.pattern = 'test/**/*_test.rb
|
24
|
+
test.pattern = ENV['TEST'] || "test/**/*_test.rb"
|
19
25
|
test.verbose = true
|
20
26
|
end
|
21
27
|
|
22
|
-
require 'rcov/rcovtask'
|
23
28
|
Rcov::RcovTask.new do |test|
|
24
29
|
test.libs << 'test' << 'test/fixtures'
|
25
30
|
test.pattern = 'test/**/*_test.rb'
|
@@ -27,12 +32,8 @@ Rcov::RcovTask.new do |test|
|
|
27
32
|
test.rcov_opts << '--exclude "gems/*"'
|
28
33
|
end
|
29
34
|
|
30
|
-
task :default => :test
|
31
|
-
|
32
|
-
require 'rake/rdoctask'
|
33
35
|
Rake::RDocTask.new do |rdoc|
|
34
36
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
35
|
-
|
36
37
|
rdoc.rdoc_dir = 'rdoc'
|
37
38
|
rdoc.title = "tenacity #{version}"
|
38
39
|
rdoc.rdoc_files.include('README*')
|
@@ -40,6 +41,16 @@ Rake::RDocTask.new do |rdoc|
|
|
40
41
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
41
42
|
end
|
42
43
|
|
43
|
-
|
44
|
-
|
44
|
+
YARD::Rake::YardocTask.new do |t|
|
45
|
+
t.files = ['lib/**/*.rb', '-', 'EXTEND.rdoc']
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'Delete rcov, rdoc, yard, and other generated files'
|
49
|
+
task :clobber => [:clobber_rcov, :clobber_rdoc, :clobber_yard]
|
50
|
+
|
51
|
+
desc 'Delete yard generated files'
|
52
|
+
task :clobber_yard do
|
53
|
+
puts 'rm -rf doc .yardoc'
|
54
|
+
FileUtils.rm_rf ['doc', '.yardoc']
|
55
|
+
end
|
45
56
|
|
data/history.txt
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
== 0.3.0
|
2
|
+
|
3
|
+
* Major enhancements
|
4
|
+
|
5
|
+
* Added support for Mongoid
|
6
|
+
* Added support for DataMapper
|
7
|
+
* Added support for Sequel
|
8
|
+
|
9
|
+
* Minor enhancements
|
10
|
+
|
11
|
+
* Automatically save object when added to a t_has_many association, unless the
|
12
|
+
parent object is not yet saved itself.
|
13
|
+
* Added suport for destroy_all to the t_has_many association
|
14
|
+
* Added suport for delete_all to the t_has_many association
|
15
|
+
* Added support for push and concat to t_has_many association
|
16
|
+
|
17
|
+
* Bug fixes
|
18
|
+
|
19
|
+
* Found and fixed many minor bugs thanks to a new test suite that tests all
|
20
|
+
associations against all supported database clients.
|
21
|
+
|
1
22
|
== 0.2.0
|
2
23
|
|
3
24
|
* Major enhancements
|
data/lib/tenacity.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.join('active_support', 'inflector')
|
2
2
|
|
3
|
+
require File.join(File.dirname(__FILE__), 'tenacity', 'associates_proxy')
|
3
4
|
require File.join(File.dirname(__FILE__), 'tenacity', 'association')
|
4
5
|
require File.join(File.dirname(__FILE__), 'tenacity', 'class_methods')
|
5
6
|
require File.join(File.dirname(__FILE__), 'tenacity', 'instance_methods')
|
@@ -7,11 +8,11 @@ require File.join(File.dirname(__FILE__), 'tenacity', 'associations', 'belongs_t
|
|
7
8
|
require File.join(File.dirname(__FILE__), 'tenacity', 'associations', 'has_many')
|
8
9
|
require File.join(File.dirname(__FILE__), 'tenacity', 'associations', 'has_one')
|
9
10
|
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'activerecord')
|
10
|
-
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'couchrest'
|
11
|
-
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', '
|
12
|
-
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'couchrest', 'couchrest_extended_document')
|
13
|
-
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'couchrest', 'couchrest_model')
|
11
|
+
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'couchrest')
|
12
|
+
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'datamapper')
|
14
13
|
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'mongo_mapper')
|
14
|
+
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'mongoid')
|
15
|
+
require File.join(File.dirname(__FILE__), 'tenacity', 'orm_ext', 'sequel')
|
15
16
|
|
16
17
|
module Tenacity #:nodoc:
|
17
18
|
include InstanceMethods
|
@@ -21,6 +22,13 @@ module Tenacity #:nodoc:
|
|
21
22
|
include HasOne
|
22
23
|
|
23
24
|
def self.included(model)
|
25
|
+
ActiveRecord.setup(model)
|
26
|
+
CouchRest.setup(model)
|
27
|
+
DataMapper.setup(model)
|
28
|
+
MongoMapper.setup(model)
|
29
|
+
Mongoid.setup(model)
|
30
|
+
Sequel.setup(model)
|
31
|
+
|
24
32
|
raise "Tenacity does not support the database client used by #{model}" unless model.respond_to?(:_t_find)
|
25
33
|
model.extend(ClassMethods)
|
26
34
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Tenacity
|
2
|
+
class AssociatesProxy #:nodoc:
|
3
|
+
alias_method :proxy_respond_to?, :respond_to?
|
4
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
|
5
|
+
|
6
|
+
def initialize(parent, target, association)
|
7
|
+
@parent = parent
|
8
|
+
@target = target
|
9
|
+
@association = association
|
10
|
+
end
|
11
|
+
|
12
|
+
def respond_to?(*args)
|
13
|
+
proxy_respond_to?(*args) || @target.respond_to?(*args)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Explicitly proxy === because the instance method removal above doesn't catch it.
|
17
|
+
def ===(other)
|
18
|
+
other === @target
|
19
|
+
end
|
20
|
+
|
21
|
+
def <<(object)
|
22
|
+
object.save unless @parent.id.nil?
|
23
|
+
@target << object
|
24
|
+
end
|
25
|
+
|
26
|
+
def push(*objects)
|
27
|
+
objects.each { |object| object.save } unless @parent.id.nil?
|
28
|
+
@target.push(*objects)
|
29
|
+
end
|
30
|
+
|
31
|
+
def concat(objects)
|
32
|
+
objects.each { |object| object.save } unless @parent.id.nil?
|
33
|
+
@target.concat(objects)
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy_all
|
37
|
+
ids = prepare_for_delete
|
38
|
+
@association.associate_class._t_delete(ids)
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete_all
|
42
|
+
ids = prepare_for_delete
|
43
|
+
@association.associate_class._t_delete(ids, false)
|
44
|
+
end
|
45
|
+
|
46
|
+
def inspect
|
47
|
+
@target.inspect
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def prepare_for_delete
|
53
|
+
ids = @parent._t_get_associate_ids(@association)
|
54
|
+
@parent._t_remove_associates(@association)
|
55
|
+
@parent.save
|
56
|
+
ids
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_missing(method, *args)
|
60
|
+
if block_given?
|
61
|
+
@target.send(method, *args) { |*block_args| yield(*block_args) }
|
62
|
+
else
|
63
|
+
@target.send(method, *args)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/tenacity/association.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
module Tenacity
|
2
|
+
|
3
|
+
# The Associaiton class represents a Tenacity association. Using this class,
|
4
|
+
# you can retrieve all sorts of information about the association, including
|
5
|
+
# it name, type, source, target class, etc.
|
2
6
|
class Association
|
7
|
+
|
3
8
|
# Type type of the association (<tt>:t_has_one</tt>, <tt>:t_has_many</tt>, or <tt>:t_belongs_to</tt>)
|
4
9
|
attr_reader :type
|
5
10
|
|
@@ -62,21 +67,29 @@ module Tenacity
|
|
62
67
|
|
63
68
|
# Get the name of the join table used by this association
|
64
69
|
def join_table
|
65
|
-
|
66
|
-
|
67
|
-
end
|
70
|
+
table_name = fetch_table_name
|
71
|
+
@join_table || (name.to_s < table_name ? "#{name}_#{table_name}" : "#{table_name}_#{name}")
|
68
72
|
end
|
69
73
|
|
70
74
|
# Get the name of the column in the join table that represents this object
|
71
75
|
def association_key
|
72
|
-
|
73
|
-
|
74
|
-
end
|
76
|
+
table_name = fetch_table_name
|
77
|
+
@association_key || table_name.singularize + '_id'
|
75
78
|
end
|
76
79
|
|
77
80
|
# Get the name of the column in the join table that represents the associated object
|
78
81
|
def association_foreign_key
|
79
82
|
@association_foreign_key || name.to_s.singularize + '_id'
|
80
83
|
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def fetch_table_name
|
88
|
+
if @source.respond_to?(:table_name)
|
89
|
+
@source.table_name.to_s
|
90
|
+
else
|
91
|
+
"#{ActiveSupport::Inflector.underscore(@source)}s"
|
92
|
+
end
|
93
|
+
end
|
81
94
|
end
|
82
95
|
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module Tenacity
|
2
2
|
module HasMany #:nodoc:
|
3
3
|
|
4
|
+
def _t_remove_associates(association)
|
5
|
+
instance_variable_set _t_ivar_name(association), []
|
6
|
+
_t_clear_associates(association)
|
7
|
+
end
|
8
|
+
|
4
9
|
private
|
5
10
|
|
6
11
|
def has_many_associates(association)
|
@@ -39,6 +44,7 @@ module Tenacity
|
|
39
44
|
|
40
45
|
associates = (record.instance_variable_get record._t_ivar_name(association)) || []
|
41
46
|
associates.each do |associate|
|
47
|
+
associate._t_reload
|
42
48
|
associate.send("#{association.foreign_key(record.class)}=", record.id.to_s)
|
43
49
|
save_associate(associate)
|
44
50
|
end
|
@@ -7,6 +7,7 @@ module Tenacity
|
|
7
7
|
# methods.
|
8
8
|
#
|
9
9
|
# class Project
|
10
|
+
# include SupportedDatabaseClient
|
10
11
|
# include Tenacity
|
11
12
|
#
|
12
13
|
# t_belongs_to :portfolio
|
@@ -57,6 +58,47 @@ module Tenacity
|
|
57
58
|
# t_belongs_to :manager # foreign key - manager_id
|
58
59
|
# end
|
59
60
|
#
|
61
|
+
# == Is it a +t_belongs_to+ or +t_has_one+ association?
|
62
|
+
#
|
63
|
+
# Both express a 1-1 relationship. The difference is mostly where to place
|
64
|
+
# the foreign key, which is owned by the class declaring the +t_belongs_to+
|
65
|
+
# relationship. Example:
|
66
|
+
#
|
67
|
+
# class Employee < ActiveRecord::Base
|
68
|
+
# include Tenacity
|
69
|
+
# t_has_one :office
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# class Office
|
73
|
+
# include MongoMapper::Document
|
74
|
+
# include Tenacity
|
75
|
+
# t_belongs_to :employee
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# In this example, the foreign key, <tt>employee_id</tt>, would belong to the
|
79
|
+
# Office class. If possible, tenacity will define the property to hold the
|
80
|
+
# foreign key. When it cannot, it assumes that the foreign key has been
|
81
|
+
# defined. See the documentation for the respective database client
|
82
|
+
# extension to see if tenacity will declare the foreign_key property.
|
83
|
+
#
|
84
|
+
# == Unsaved objects and associations
|
85
|
+
#
|
86
|
+
# You can manipulate objects and associations before they are saved to the database, but there is some special behavior you should be
|
87
|
+
# aware of, mostly involving the saving of associated objects.
|
88
|
+
#
|
89
|
+
# === One-to-one associations
|
90
|
+
#
|
91
|
+
# * Assigning an object to a +t_has_one+ association automatically saves that object and the object being replaced (if there is one), in
|
92
|
+
# order to update their primary keys - except if the parent object is not yet stored in the database.
|
93
|
+
# * Assigning an object to a +t_belongs_to+ association does not save the object, since the foreign key field belongs on the parent. It
|
94
|
+
# does not save the parent either.
|
95
|
+
#
|
96
|
+
# === Collections
|
97
|
+
#
|
98
|
+
# * Adding an object to a collection (+t_has_many+) automatically saves that object, except if the parent object
|
99
|
+
# (the owner of the collection) is not yet stored in the database.
|
100
|
+
# * All unsaved members of the collection are automatically saved when the parent is saved.
|
101
|
+
#
|
60
102
|
# == Caching
|
61
103
|
#
|
62
104
|
# All of the methods are built on a simple caching principle that will keep the result
|
@@ -218,9 +260,18 @@ module Tenacity
|
|
218
260
|
# An empty array is returned if none are found.
|
219
261
|
# [collection<<(object, ...)]
|
220
262
|
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
221
|
-
#
|
263
|
+
# [collection.push(object, ...)]
|
264
|
+
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
265
|
+
# [collection.concat(other_array)]
|
266
|
+
# Adds the objects in the other array to the collection by setting their foreign keys to the collection's primary key.
|
222
267
|
# [collection.delete(object, ...)]
|
223
268
|
# Removes one or more objects from the collection.
|
269
|
+
# [collection.destroy_all]
|
270
|
+
# Removes all objects from the collection, and deletes them from their respective
|
271
|
+
# database. If the deleted objects have any delete callbacks defined, they will be called.
|
272
|
+
# [collection.delete_all]
|
273
|
+
# Removes all objects from the collection, and deletes them from their respective
|
274
|
+
# database. No delete callbacks will be called, regardless of whether or not they are defined.
|
224
275
|
# [collection=objects]
|
225
276
|
# Replaces the collections content by setting it to the list of specified objects.
|
226
277
|
# [collection_singular_ids]
|
@@ -8,11 +8,11 @@ module Tenacity
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def get_associate(association, params)
|
11
|
-
_t_reload
|
11
|
+
_t_reload unless id.nil?
|
12
12
|
force_reload = params.first unless params.empty?
|
13
|
-
value = instance_variable_get
|
13
|
+
value = create_proxy(instance_variable_get(_t_ivar_name(association)), association)
|
14
14
|
if value.nil? || force_reload
|
15
|
-
value = yield
|
15
|
+
value = create_proxy(yield, association)
|
16
16
|
instance_variable_set _t_ivar_name(association), value
|
17
17
|
end
|
18
18
|
value
|
@@ -23,5 +23,9 @@ module Tenacity
|
|
23
23
|
instance_variable_set _t_ivar_name(association), associate
|
24
24
|
end
|
25
25
|
|
26
|
+
def create_proxy(value, association)
|
27
|
+
value.respond_to?(:each) ? AssociatesProxy.new(self, value, association) : value
|
28
|
+
end
|
29
|
+
|
26
30
|
end
|
27
31
|
end
|
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'active_record'
|
3
|
-
|
1
|
+
module Tenacity
|
4
2
|
# Tenacity relationships on ActiveRecord objects require that certain columns
|
5
3
|
# exist on the associated table, and that join tables exist for one-to-many
|
6
4
|
# relationships. Take the following class for example:
|
@@ -43,33 +41,53 @@ begin
|
|
43
41
|
# end
|
44
42
|
#
|
45
43
|
module ActiveRecord
|
46
|
-
class Base #:nodoc:
|
47
44
|
|
48
|
-
|
45
|
+
def self.setup(model)
|
46
|
+
require 'active_record'
|
47
|
+
if model.ancestors.include?(::ActiveRecord::Base)
|
48
|
+
model.send :include, ActiveRecord::InstanceMethods
|
49
|
+
model.extend ActiveRecord::ClassMethods
|
50
|
+
end
|
51
|
+
rescue LoadError
|
52
|
+
# ActiveRecord not available
|
53
|
+
end
|
54
|
+
|
55
|
+
module ClassMethods #:nodoc:
|
56
|
+
def _t_find(id)
|
49
57
|
find_by_id(id)
|
50
58
|
end
|
51
59
|
|
52
|
-
def
|
60
|
+
def _t_find_bulk(ids)
|
53
61
|
return [] if ids.nil? || ids.empty?
|
54
62
|
find(:all, :conditions => ["id in (?)", ids])
|
55
63
|
end
|
56
64
|
|
57
|
-
def
|
65
|
+
def _t_find_first_by_associate(property, id)
|
58
66
|
find(:first, :conditions => ["#{property} = ?", id.to_s])
|
59
67
|
end
|
60
68
|
|
61
|
-
def
|
69
|
+
def _t_find_all_by_associate(property, id)
|
62
70
|
find(:all, :conditions => ["#{property} = ?", id.to_s])
|
63
71
|
end
|
64
72
|
|
65
|
-
def
|
73
|
+
def _t_initialize_has_many_association(association)
|
66
74
|
after_save { |record| record.class._t_save_associates(record, association) }
|
67
75
|
end
|
68
76
|
|
69
|
-
def
|
77
|
+
def _t_initialize_belongs_to_association(association)
|
70
78
|
before_save { |record| record.class._t_stringify_belongs_to_value(record, association) }
|
71
79
|
end
|
72
80
|
|
81
|
+
def _t_delete(ids, run_callbacks=true)
|
82
|
+
if run_callbacks
|
83
|
+
destroy_all(["id in (?)", ids])
|
84
|
+
else
|
85
|
+
delete_all(["id in (?)", ids])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
module InstanceMethods #:nodoc:
|
73
91
|
def _t_reload
|
74
92
|
reload
|
75
93
|
end
|
@@ -88,12 +106,11 @@ begin
|
|
88
106
|
end
|
89
107
|
|
90
108
|
def _t_get_associate_ids(association)
|
109
|
+
return [] if self.id.nil?
|
91
110
|
rows = self.connection.execute("select #{association.association_foreign_key} from #{association.join_table} where #{association.association_key} = #{self.id}")
|
92
111
|
ids = []; rows.each { |r| ids << r[0] }; ids
|
93
112
|
end
|
94
|
-
|
95
113
|
end
|
114
|
+
|
96
115
|
end
|
97
|
-
rescue LoadError
|
98
|
-
# ActiveRecord not available
|
99
116
|
end
|