acts-as-joinable 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/acts_as_joinable/core.rb +73 -63
- metadata +3 -3
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
|
|
5
5
|
spec = Gem::Specification.new do |s|
|
6
6
|
s.name = "acts-as-joinable"
|
7
7
|
s.authors = ["Lance Pollard"]
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.3"
|
9
9
|
s.summary = "ActsAsJoinable: DRYing up Many-to-Many Relationships in ActiveRecord"
|
10
10
|
s.homepage = "http://github.com/viatropos/acts-as-joinable"
|
11
11
|
s.email = "lancejpollard@gmail.com"
|
@@ -42,35 +42,35 @@ module ActsAsJoinable
|
|
42
42
|
def initialize_acts_as_joinable_on_core
|
43
43
|
joins = acts_as_joinable_config.dup
|
44
44
|
block = joins.pop
|
45
|
-
|
45
|
+
opts = joins.extract_options!
|
46
46
|
if joins.empty?
|
47
47
|
joins = ActsAsJoinable.models
|
48
48
|
relationships = [:child]
|
49
49
|
else
|
50
|
-
relationships = [
|
50
|
+
relationships = [opts[:as] || :parent].flatten.map(&:to_sym)
|
51
51
|
end
|
52
52
|
|
53
|
-
|
53
|
+
opts[:class_name] ||= opts[:source].to_s.camelize if opts[:source]
|
54
54
|
|
55
|
-
association_type =
|
55
|
+
association_type = opts[:limit] == 1 ? :has_one : :has_many
|
56
56
|
|
57
|
-
scope_name =
|
57
|
+
scope_name = opts[:named_scope]
|
58
58
|
|
59
59
|
joins.map!(&:to_sym)
|
60
60
|
|
61
61
|
# class name of the model we're joining to self
|
62
62
|
# otherwise it's retrieved from joins.each...
|
63
|
-
class_name =
|
63
|
+
class_name = opts[:class_name] || nil
|
64
64
|
# contexts defining the relationship between self and target
|
65
|
-
contexts = [
|
65
|
+
contexts = [opts[:context] || []].flatten
|
66
66
|
context = contexts.first
|
67
67
|
# possible values of the context
|
68
|
-
values = [
|
68
|
+
values = [opts[:values] || opts[:value] || []].flatten.compact
|
69
69
|
value = values.first
|
70
70
|
|
71
|
-
sql =
|
71
|
+
sql = opts[:conditions]
|
72
72
|
|
73
|
-
nestable =
|
73
|
+
nestable = opts[:nestable] || false
|
74
74
|
|
75
75
|
# parent, child, or contexts (both) for custom helper getters/setters
|
76
76
|
|
@@ -89,75 +89,72 @@ module ActsAsJoinable
|
|
89
89
|
joins.each do |type|
|
90
90
|
singular_type = type.to_s.singularize
|
91
91
|
if association_type == :has_one
|
92
|
-
plural_type = type.to_s.pluralize
|
92
|
+
plural_type = type.to_s.pluralize.to_sym
|
93
93
|
else
|
94
|
-
plural_type = type.to_s
|
94
|
+
plural_type = type.to_s.to_sym
|
95
95
|
end
|
96
|
-
class_name =
|
96
|
+
class_name = opts[:class_name] || type.to_s.classify
|
97
97
|
|
98
98
|
join_context = (context || singular_type).to_s
|
99
99
|
|
100
100
|
options = {
|
101
|
-
:through
|
102
|
-
:class_name
|
103
|
-
:source
|
104
|
-
:source_type
|
105
|
-
:conditions
|
101
|
+
:through => :relationships,
|
102
|
+
:class_name => class_name,
|
103
|
+
:source => :child,
|
104
|
+
:source_type => class_name,
|
105
|
+
:conditions => sql
|
106
106
|
}
|
107
107
|
|
108
108
|
# relationships == [:parent, :child]
|
109
109
|
relationships.each do |relationship|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
# Post.joins :tags, :as => :parent
|
111
|
+
# through_relationship = child_tag_relationships
|
112
|
+
# relationship_table = `relationships`
|
113
|
+
relationship = opposite_for(relationship)
|
114
|
+
through_relationship = "#{relationship.to_s}_#{singular_type}_relationships".to_sym
|
115
|
+
relationship_table = ActsAsJoinable::Relationship.quoted_table_name
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
+
options.merge!(:through => through_relationship, :source => relationship, :uniq => true)
|
118
|
+
|
119
|
+
join_value = value
|
120
|
+
|
121
|
+
# conditions for the join model
|
122
|
+
condition_string = ""
|
123
|
+
#if join_context == class_name.underscore
|
124
|
+
|
125
|
+
# condition_string << "(#{relationship_table}.#{relationship}_type IN (?))"
|
126
|
+
if join_context == class_name.underscore
|
127
|
+
#conditions = [condition_string, [class_name]]
|
117
128
|
else
|
118
|
-
|
129
|
+
condition_string << "(#{relationship_table}.context IN (?))"
|
130
|
+
condition_string << " AND (#{relationship_table}.value = ?)" if join_value
|
131
|
+
join_contexts = [join_context]#[join_context, class_name.underscore].uniq
|
132
|
+
conditions = [condition_string, join_contexts]
|
133
|
+
conditions << join_value.to_s if join_value
|
119
134
|
end
|
120
135
|
|
121
|
-
|
122
|
-
:
|
123
|
-
:
|
124
|
-
|
136
|
+
through_options = {
|
137
|
+
:class_name => "ActsAsJoinable::Relationship",
|
138
|
+
:conditions => conditions,
|
139
|
+
:as => opposite_for(relationship).to_sym
|
140
|
+
}
|
125
141
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
conditions = [condition_string, join_contexts]
|
132
|
-
conditions << join_value.to_s if join_value
|
133
|
-
|
134
|
-
through_options = {
|
135
|
-
:class_name => "ActsAsJoinable::Relationship",
|
136
|
-
:conditions => conditions,
|
137
|
-
:as => opposite_for(relationship).to_sym
|
138
|
-
}
|
139
|
-
|
140
|
-
through_options[:uniq] = true unless association_type == :has_one
|
141
|
-
|
142
|
-
# has_many :member_relationships
|
143
|
-
# conditions: context == x, value == y
|
144
|
-
send(:has_many, relationship_with_context, through_options)
|
145
|
-
|
146
|
-
options = options.merge(
|
147
|
-
:through => relationship_with_context,
|
148
|
-
:source => relationship,
|
149
|
-
:uniq => true
|
150
|
-
)
|
142
|
+
if association_type == :has_one
|
143
|
+
options.delete(:after_add)
|
144
|
+
options.delete(:uniq)
|
145
|
+
else
|
146
|
+
through_options[:uniq] = true
|
151
147
|
end
|
152
148
|
|
153
|
-
|
154
|
-
|
149
|
+
unless has_association?(through_relationship)
|
150
|
+
has_many through_relationship, through_options
|
151
|
+
end
|
155
152
|
|
156
|
-
method_scope = association_type == :has_one ? :protected : :public
|
157
|
-
#send(method_scope)
|
158
|
-
# has_many :child_users, :through => :child_relationships
|
159
153
|
add_association(relationship.to_s, plural_type, options, join_context, join_value, nestable, &block)
|
160
|
-
|
154
|
+
|
155
|
+
if association_type == :has_one
|
156
|
+
add_has_one(singular_type, plural_type, through_relationship, class_name)
|
157
|
+
end
|
161
158
|
end
|
162
159
|
end
|
163
160
|
end
|
@@ -172,12 +169,16 @@ module ActsAsJoinable
|
|
172
169
|
role.to_s == "parent" ? "child" : "parent"
|
173
170
|
end
|
174
171
|
|
172
|
+
def has_association?(name)
|
173
|
+
self.reflect_on_all_associations.map(&:name).include?(name.to_sym)
|
174
|
+
end
|
175
|
+
|
175
176
|
def add_has_one(singular_type, plural_type, relationship_with_context, class_name)
|
176
177
|
define_method singular_type do
|
177
178
|
send(plural_type).last
|
178
179
|
end
|
179
180
|
define_method "#{singular_type}=" do |value|
|
180
|
-
|
181
|
+
send(relationship_with_context).delete_all
|
181
182
|
send(plural_type) << value
|
182
183
|
end
|
183
184
|
define_method "#{singular_type}_id" do
|
@@ -192,15 +193,24 @@ module ActsAsJoinable
|
|
192
193
|
eval_options = {:context => join_context}
|
193
194
|
eval_options[:value] = join_value unless join_value.blank?
|
194
195
|
# has_many :users, :through => :child_relationships
|
196
|
+
plural_relationship = "#{relationship}_#{plural_type}".to_sym
|
197
|
+
unless has_association?(plural_relationship)
|
198
|
+
send(:has_many, plural_relationship, options) do
|
199
|
+
class_eval <<-EOF
|
200
|
+
def construct_join_attributes(associate)
|
201
|
+
super.merge(#{eval_options.inspect})
|
202
|
+
end
|
203
|
+
EOF
|
204
|
+
end
|
205
|
+
end
|
195
206
|
|
196
|
-
unless
|
207
|
+
unless has_association?(plural_type)
|
197
208
|
send(:has_many, plural_type.to_sym, options) do
|
198
209
|
class_eval <<-EOF
|
199
210
|
def construct_join_attributes(associate)
|
200
211
|
super.merge(#{eval_options.inspect})
|
201
212
|
end
|
202
213
|
EOF
|
203
|
-
|
204
214
|
end
|
205
215
|
accepts_nested_attributes_for plural_type.to_sym if nestable
|
206
216
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts-as-joinable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Lance Pollard
|