arusarka-dynamic-active-resource 0.2.2 → 0.2.3
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/lib/dynamic_active_resource.rb +21 -0
- data/lib/dynamic_active_resource/associations.rb +21 -0
- data/lib/dynamic_active_resource/associations/base.rb +23 -0
- data/lib/dynamic_active_resource/associations/belongs_to.rb +11 -0
- data/lib/dynamic_active_resource/associations/has_many.rb +17 -0
- data/lib/dynamic_active_resource/base.rb +210 -0
- data/lib/dynamic_active_resource/common_class_methods.rb +131 -0
- data/lib/dynamic_active_resource/common_dynamic_class_instance_methods.rb +38 -0
- data/lib/dynamic_active_resource/helpers.rb +33 -0
- data/lib/dynamic_active_resource/version.rb +11 -0
- metadata +11 -1
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'active_resource'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
require 'active_resource'
|
6
|
+
end
|
7
|
+
|
8
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
9
|
+
|
10
|
+
require 'dynamic_active_resource/associations'
|
11
|
+
require 'dynamic_active_resource/common_dynamic_class_instance_methods'
|
12
|
+
require 'dynamic_active_resource/common_class_methods'
|
13
|
+
require 'dynamic_active_resource/helpers'
|
14
|
+
require 'dynamic_active_resource/version'
|
15
|
+
require 'dynamic_active_resource/base'
|
16
|
+
|
17
|
+
module DynamicActiveResource
|
18
|
+
end
|
19
|
+
|
20
|
+
# shorter name
|
21
|
+
DynAR = DynamicActiveResource
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'dynamic_active_resource/associations/base'
|
2
|
+
require 'dynamic_active_resource/associations/has_many'
|
3
|
+
require 'dynamic_active_resource/associations/belongs_to'
|
4
|
+
|
5
|
+
module DynamicActiveResource
|
6
|
+
module Associations
|
7
|
+
def has_many(assosiation_sym, options = {})
|
8
|
+
h_m_association = HasMany.new(assosiation_sym, options)
|
9
|
+
associations = self.instance_variable_get(:@associations) || []
|
10
|
+
associations << h_m_association
|
11
|
+
self.instance_variable_set(:@associations, associations)
|
12
|
+
end
|
13
|
+
|
14
|
+
def belongs_to(association_sym, options = {})
|
15
|
+
b_t_association = BelongsTo.new(association_sym, options)
|
16
|
+
associations = self.instance_variable_get(:@associations) || []
|
17
|
+
associations << b_t_association
|
18
|
+
self.instance_variable_set(:@associations, associations)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DynamicActiveResource
|
2
|
+
module Associations
|
3
|
+
class Base
|
4
|
+
attr_reader :method_name
|
5
|
+
def initialize(method_name, options = {})
|
6
|
+
@method_name = method_name.to_s
|
7
|
+
class_name = options[:through] || @method_name.singularize.camelize
|
8
|
+
@associated_class_name = class_name
|
9
|
+
end
|
10
|
+
|
11
|
+
# fetches the resources for the association. requires the caller to be
|
12
|
+
# passed through self.
|
13
|
+
def resources_for(caller)
|
14
|
+
raise 'Not Implemented'
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def associated_class
|
19
|
+
eval(@associated_class_name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module DynamicActiveResource
|
2
|
+
module Associations
|
3
|
+
class BelongsTo < Associations::Base
|
4
|
+
def resources_for(caller)
|
5
|
+
site_elements = caller.class.site.path.split('/')
|
6
|
+
associated_resource_id = site_elements[-1]
|
7
|
+
associated_class.find(associated_resource_id)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DynamicActiveResource
|
2
|
+
module Associations
|
3
|
+
class HasMany < Base
|
4
|
+
def set_associated_class_attributes(caller)
|
5
|
+
associated_class_site = File.join(caller.class.site.to_s, caller.class.collection_name, caller.resource_identifier)
|
6
|
+
associated_class.site = associated_class_site
|
7
|
+
associated_class.user = caller.class.user
|
8
|
+
associated_class.password = caller.class.password
|
9
|
+
end
|
10
|
+
|
11
|
+
def resources_for(caller)
|
12
|
+
set_associated_class_attributes(caller)
|
13
|
+
associated_class.find(:all)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
module DynamicActiveResource
|
2
|
+
# ActiveResource makes connecting to rest resources very easy. However it has one problem
|
3
|
+
# and a big one at that. If you try setting the authentication credentials or the site or
|
4
|
+
# collection name, element name for the class for the second time it doesn't work. E.g.
|
5
|
+
#
|
6
|
+
# class Person < ActiveResource::Base
|
7
|
+
# self.site = 'http://localhost:9090/'
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# After sometime you change it to
|
11
|
+
#
|
12
|
+
# Person.site = 'https://org-server/my_proj/'
|
13
|
+
# Person.user = 'admin'
|
14
|
+
# Person.password = 'secret'
|
15
|
+
#
|
16
|
+
# Then you do
|
17
|
+
#
|
18
|
+
# Person.find(:all) => It bombs
|
19
|
+
#
|
20
|
+
# This class provides a mechanism by which you can get rid of this problem. Extend DynamicActiveResource::Base
|
21
|
+
# class in the actual class itself. Do not extend the extended class from ActiveResource::Base.
|
22
|
+
#
|
23
|
+
# E.g.
|
24
|
+
#
|
25
|
+
# class Person < DynamicActiveResource::Base
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# set the credentials
|
29
|
+
#
|
30
|
+
# Person.site = 'http://localhost:8080'
|
31
|
+
# Person.user = 'foo'
|
32
|
+
# Person.password = 'bar'
|
33
|
+
#
|
34
|
+
# Thats it. Now create some objects
|
35
|
+
#
|
36
|
+
# asur = Person.new(:name => 'Asur', :job => 'fooling around', :status => 'Single and ready 2 mingle')
|
37
|
+
# asur.save
|
38
|
+
#
|
39
|
+
# Now change the class attributes
|
40
|
+
#
|
41
|
+
# Person.site = 'https://org-server/mingle'
|
42
|
+
# Person.collection_name = 'boring_people'
|
43
|
+
#
|
44
|
+
# Now instantiate an object
|
45
|
+
#
|
46
|
+
# rakhshas = Person.new(:name => 'Rakhshas', :job => 'eating people', :status => 'just woke up and hungry')
|
47
|
+
# rakhshas.save => Voila !!!!!!! it works
|
48
|
+
#
|
49
|
+
# CUSTOMIZATIONS
|
50
|
+
# --------------
|
51
|
+
#
|
52
|
+
# No amount of wrapping can provide very detailed customizations. Either you have a lot of methods
|
53
|
+
# that are not being used or there is hardly anything at all. To oversome this problem this module
|
54
|
+
# was written to provide only those methods which are common to most active resource objects.
|
55
|
+
# However if you want to have a little more control over your active resource objects its very easy.
|
56
|
+
# Here's how you would do it normally
|
57
|
+
#
|
58
|
+
# class Person < ActiveResource::Base
|
59
|
+
# def self.count
|
60
|
+
# find(:all).size
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# def occupation
|
64
|
+
# return job if job
|
65
|
+
# 'Unemployed'
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# To do the same thing, here's how you do it using this library
|
70
|
+
#
|
71
|
+
# class Person < DynamicActiveResource::Base
|
72
|
+
# module DynamicClassSingletonMethods
|
73
|
+
# def count
|
74
|
+
# find(:all).size
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# module DynamicClassInstanceMethods
|
79
|
+
# def occupation
|
80
|
+
# return job if job
|
81
|
+
# 'Unemployed'
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# The DynamicClassInstanceMethods will be available as instance methods in the objects created,
|
87
|
+
# DynamicClassSingletonMethods will be available as class methods in the class of the object. Also
|
88
|
+
# active resource associations are sometimes paginated. So even if you use find(:all), you get
|
89
|
+
# only the first few results. To overcome this, include in your DynamicClassSingletonMethods module
|
90
|
+
# a method called find_without_pagination. In that method route it to acitve resource find with
|
91
|
+
# proper parameters. An example of the method implementation is
|
92
|
+
#
|
93
|
+
# module DynamicClassSingletonMethods
|
94
|
+
# def find_without_pagination(*args)
|
95
|
+
# scope = args.slice!(0)
|
96
|
+
# options = args.slice!(0) || {}
|
97
|
+
# options[:params] ||= {}
|
98
|
+
# options[:params].merge!({:page => 'all'})
|
99
|
+
# # call ActiveResource::Base::find with proper options
|
100
|
+
# find(scope, options)
|
101
|
+
# end
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# The class level find method will automatically pick up this method if defined as a method in the
|
105
|
+
# DynamicClassSingeletonMethod module else it will pass it to find.
|
106
|
+
#
|
107
|
+
# ASSOCIATIONS
|
108
|
+
# ------------
|
109
|
+
#
|
110
|
+
# This gem also provides active record like associations(highly experimental). Right now it provides only two
|
111
|
+
# associations - 1) has_many, 2) belongs_to.
|
112
|
+
#
|
113
|
+
# 1) has_many
|
114
|
+
# -----------
|
115
|
+
#
|
116
|
+
# Taking the example from above the way it should be done
|
117
|
+
#
|
118
|
+
# class Person < DynamicActiveResource::Base
|
119
|
+
# has_many :cars
|
120
|
+
#
|
121
|
+
# module DynamicClassSingletonMethods
|
122
|
+
# def count
|
123
|
+
# find(:all).size
|
124
|
+
# end
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# module DynamicClassInstanceMethods
|
128
|
+
# def occupation
|
129
|
+
# return job if job
|
130
|
+
# 'Unemployed'
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# def resource_identifier
|
134
|
+
# name()
|
135
|
+
# end
|
136
|
+
# end
|
137
|
+
# end
|
138
|
+
#
|
139
|
+
# Next a car class has to be initialized
|
140
|
+
#
|
141
|
+
# class Car < DynARBase (alias for DynamicActiveResource::Base, inbuilt in the gem)
|
142
|
+
# end
|
143
|
+
#
|
144
|
+
# set resource options only at the top level( Person in this case)
|
145
|
+
#
|
146
|
+
# Person.site = 'http://localhost:8080/'
|
147
|
+
# Person.user = 'test'
|
148
|
+
# Person.password = 'secret'
|
149
|
+
#
|
150
|
+
# associations take care of setting the site in the children classes automatically
|
151
|
+
# you will notice that an additional method resource_identifier() has been defined
|
152
|
+
# in the parent class. It would be discussed shortly.
|
153
|
+
#
|
154
|
+
# The way associations work is if you do something like
|
155
|
+
#
|
156
|
+
# person = Person.find('asur').cars it will hit the url http://localhost:8080/people/asur/cars.xml
|
157
|
+
#
|
158
|
+
# You would notice that its getting the cars for the person with name 'asur'. It does so because
|
159
|
+
# in the Person class a method called resource_identifier has been defined which says that the id
|
160
|
+
# is actually name instead of the database id. If the id attribute in the xml is set appropriately
|
161
|
+
# (to 'name' in this case) then you do not need to define the method.
|
162
|
+
#
|
163
|
+
# 2) belongs_to
|
164
|
+
# -------------
|
165
|
+
#
|
166
|
+
# Again, referring to the example above
|
167
|
+
#
|
168
|
+
# class Person < DynamicActiveResource::Base
|
169
|
+
# has_many :cars
|
170
|
+
#
|
171
|
+
# module DynamicClassSingletonMethods
|
172
|
+
# def count
|
173
|
+
# find(:all).size
|
174
|
+
# end
|
175
|
+
# end
|
176
|
+
#
|
177
|
+
# module DynamicClassInstanceMethods
|
178
|
+
# def occupation
|
179
|
+
# return job if job
|
180
|
+
# 'Unemployed'
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# def resource_identifier
|
184
|
+
# name()
|
185
|
+
# end
|
186
|
+
# end
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# Next a car class has to be initialized
|
190
|
+
#
|
191
|
+
# class Car < DynARBase (alias for DynamicActiveResource::Base)
|
192
|
+
# belongs_to :person
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# Right now belongs_to supports only assocation with a single class. After defining this you
|
196
|
+
# automatically have a method 'person' available.
|
197
|
+
#
|
198
|
+
# car = Car.find('WB1234I')
|
199
|
+
# owner = car.person
|
200
|
+
|
201
|
+
class Base < ActiveResource::Base
|
202
|
+
def self.inherited(subclass)
|
203
|
+
subclass.extend(DynamicActiveResource::CommonClassMethods)
|
204
|
+
subclass.extend(DynamicActiveResource::Associations)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# shorter name
|
210
|
+
DynARBase = DynamicActiveResource::Base
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module DynamicActiveResource
|
2
|
+
module CommonClassMethods
|
3
|
+
attr_reader :site, :user, :password
|
4
|
+
|
5
|
+
# creates an object of the class in which this module is extended
|
6
|
+
def new(args = {})
|
7
|
+
# @resource_class = create_resource_class() # should this be commented
|
8
|
+
@resource_class.new(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
# sets the site for the class in which this module is extended
|
12
|
+
def site=(site)
|
13
|
+
if site != self.site
|
14
|
+
@site = site
|
15
|
+
uri = URI.parse(site)
|
16
|
+
@user = URI.decode(uri.user) if(uri.user)
|
17
|
+
@password = URI.decode(uri.password) if(uri.password)
|
18
|
+
@resource_class = self.send(:create_resource_class)
|
19
|
+
end
|
20
|
+
@site
|
21
|
+
end
|
22
|
+
|
23
|
+
# sets the user for the class in which this module is extended
|
24
|
+
def user=(user)
|
25
|
+
if user != self.user
|
26
|
+
@user = user
|
27
|
+
@resource_class = self.send(:create_resource_class) if(site)
|
28
|
+
end
|
29
|
+
@user
|
30
|
+
end
|
31
|
+
|
32
|
+
# sets the password for the class in which this module is extended
|
33
|
+
def password=(password)
|
34
|
+
if password != self.password
|
35
|
+
@password = password
|
36
|
+
@resource_class = self.send(:create_resource_class) if(site)
|
37
|
+
end
|
38
|
+
@password
|
39
|
+
end
|
40
|
+
|
41
|
+
# sets the collection name for the class in which this module is extended
|
42
|
+
def collection_name=(collection_name)
|
43
|
+
if collection_name != self.collection_name
|
44
|
+
@collection_name = collection_name
|
45
|
+
end
|
46
|
+
@collection_name
|
47
|
+
end
|
48
|
+
|
49
|
+
# sets the elment name for the class in which this module is extended
|
50
|
+
def element_name=(element_name)
|
51
|
+
if element_name != self.element_name
|
52
|
+
@element_name = element_name
|
53
|
+
end
|
54
|
+
@element_name
|
55
|
+
end
|
56
|
+
|
57
|
+
# collection name for the class in which this module is extended
|
58
|
+
def collection_name
|
59
|
+
@collection_name || class_name.underscore.pluralize
|
60
|
+
end
|
61
|
+
|
62
|
+
# element name for the class in which this module is extended
|
63
|
+
def element_name
|
64
|
+
@element_name || class_name.underscore
|
65
|
+
end
|
66
|
+
|
67
|
+
# routes to active resource find
|
68
|
+
def find(*args)
|
69
|
+
return @resource_class.find_without_pagination(*args) if(@resource_class.respond_to?(:find_without_pagination))
|
70
|
+
scope = args.slice!(0)
|
71
|
+
options = args.slice!(0) || {}
|
72
|
+
obj = @resource_class.find(scope, options)
|
73
|
+
obj
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
# creates an active resource class dynamically. All the attributes are set automatically. Avoid calling
|
78
|
+
# this method directly
|
79
|
+
def create_resource_class
|
80
|
+
# raise exceptions if any of site is not set
|
81
|
+
raise "Please set the site for #{self} class before using create_resource_class()." unless(self.site)
|
82
|
+
|
83
|
+
created_class = Class.new(ActiveResource::Base)
|
84
|
+
|
85
|
+
# set the resource options
|
86
|
+
created_class.site = self.site
|
87
|
+
created_class.user = self.user
|
88
|
+
created_class.password = self.password
|
89
|
+
created_class.collection_name = self.collection_name
|
90
|
+
created_class.element_name = self.element_name
|
91
|
+
|
92
|
+
created_class_name = "#{self}::#{class_name}#{Helpers.fast_token()}"
|
93
|
+
eval "#{created_class_name} = created_class"
|
94
|
+
|
95
|
+
# include the common dynamic methods
|
96
|
+
created_class.send(:include, DynamicActiveResource::CommonDynamicClassInstanceMethods)
|
97
|
+
|
98
|
+
# includes a module called InstanceMethods in the class created dynamically
|
99
|
+
# if it is defined inside the wrapper class
|
100
|
+
inst_meth_mod_name = instance_methods_module_name()
|
101
|
+
created_class.send(:include, self.const_get(inst_meth_mod_name.to_sym)) if inst_meth_mod_name
|
102
|
+
|
103
|
+
# extends the class created dynamically with a module called ClassMethods if
|
104
|
+
# it is defined inside the wrapper class
|
105
|
+
class_meth_mod_name = class_methods_module_name()
|
106
|
+
created_class.extend(self.const_get(class_meth_mod_name)) if class_meth_mod_name
|
107
|
+
# put the associations in the created class also
|
108
|
+
created_class.instance_variable_set(:@associations, @associations)
|
109
|
+
|
110
|
+
created_class
|
111
|
+
end
|
112
|
+
|
113
|
+
def class_name
|
114
|
+
self.name.split('::')[-1]
|
115
|
+
end
|
116
|
+
|
117
|
+
def instance_methods_module_name
|
118
|
+
inst_meth_mod_name = 'DynamicClassInstanceMethods'
|
119
|
+
self.constants.detect { |const| const.split('::')[-1] =~ /#{inst_meth_mod_name}/ }
|
120
|
+
end
|
121
|
+
|
122
|
+
def class_methods_module_name
|
123
|
+
class_meth_mod_name = 'DynamicClassSingletonMethods'
|
124
|
+
self.constants.detect { |const| const.split('::')[-1] =~ /#{class_meth_mod_name}/ }
|
125
|
+
end
|
126
|
+
|
127
|
+
def method_missing(meth_id, *args, &block)
|
128
|
+
@resource_class.send(meth_id, *args, &block)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module DynamicActiveResource
|
2
|
+
module CommonDynamicClassInstanceMethods
|
3
|
+
def method_missing(method_symbol, *arguments) #:nodoc:
|
4
|
+
method_name = method_symbol.to_s
|
5
|
+
# dynamic setters and getters
|
6
|
+
case method_name.last
|
7
|
+
when "="
|
8
|
+
return attributes[method_name.first(-1)] = arguments.first
|
9
|
+
when "?"
|
10
|
+
return attributes[method_name.first(-1)]
|
11
|
+
else
|
12
|
+
# return attributes
|
13
|
+
return attributes[method_name] if(attributes.has_key?(method_name))
|
14
|
+
# return the association if it is a association method
|
15
|
+
return get_association(method_name) if(association_method?(method_name))
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def resource_identifier
|
21
|
+
id()
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def association_method?(method_name)
|
26
|
+
@associations ||= self.class.instance_variable_get(:@associations)
|
27
|
+
return false unless @associations
|
28
|
+
association = @associations.detect { |association| association.method_name.to_s == method_name.to_s }
|
29
|
+
association ? true : false
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_association(method_name)
|
33
|
+
@associations ||= self.class.instance_variable_get(:@associations)
|
34
|
+
association = @associations.detect { |association| association.method_name.to_s == method_name.to_s }
|
35
|
+
association.resources_for(self)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DynamicActiveResource
|
2
|
+
module Helpers
|
3
|
+
def Helpers.fast_token
|
4
|
+
values = [
|
5
|
+
rand(0x0010000),
|
6
|
+
rand(0x0010000),
|
7
|
+
rand(0x0010000),
|
8
|
+
rand(0x0010000),
|
9
|
+
rand(0x0010000),
|
10
|
+
rand(0x1000000),
|
11
|
+
rand(0x1000000),
|
12
|
+
]
|
13
|
+
"%04x%04x%04x%04x%04x%06x%06x" % values
|
14
|
+
end
|
15
|
+
|
16
|
+
def Helpers.encode2html(string)
|
17
|
+
html_char_map = {
|
18
|
+
'[' => '%5B', ']' => '%5D',
|
19
|
+
'(' => '%28', ')' => '%29',
|
20
|
+
',' => '%2C', ' ' => '%20',
|
21
|
+
'=' => '%3D', '\'' => '%27',
|
22
|
+
'<' => '%3C', '>' => '%3E',
|
23
|
+
}
|
24
|
+
|
25
|
+
string.strip! if string
|
26
|
+
encoded_string = ''
|
27
|
+
string.each_char do |char|
|
28
|
+
encoded_string << (html_char_map[char] || char)
|
29
|
+
end
|
30
|
+
encoded_string
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arusarka-dynamic-active-resource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- asur
|
@@ -31,6 +31,16 @@ extensions: []
|
|
31
31
|
extra_rdoc_files:
|
32
32
|
- README
|
33
33
|
files:
|
34
|
+
- lib/dynamic_active_resource/associations/base.rb
|
35
|
+
- lib/dynamic_active_resource/associations/belongs_to.rb
|
36
|
+
- lib/dynamic_active_resource/associations/has_many.rb
|
37
|
+
- lib/dynamic_active_resource/associations.rb
|
38
|
+
- lib/dynamic_active_resource/base.rb
|
39
|
+
- lib/dynamic_active_resource/common_class_methods.rb
|
40
|
+
- lib/dynamic_active_resource/common_dynamic_class_instance_methods.rb
|
41
|
+
- lib/dynamic_active_resource/helpers.rb
|
42
|
+
- lib/dynamic_active_resource/version.rb
|
43
|
+
- lib/dynamic_active_resource.rb
|
34
44
|
- README
|
35
45
|
- History.txt
|
36
46
|
- init.rb
|