activerecord_where_assoc 0.1.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,4 +3,7 @@
3
3
  module ActiveRecordWhereAssoc
4
4
  class MySQLDoesntSupportSubLimitError < StandardError
5
5
  end
6
+
7
+ class PolymorphicBelongsToWithoutClasses < StandardError
8
+ end
6
9
  end
@@ -3,161 +3,359 @@
3
3
  require_relative "active_record_compat"
4
4
  require_relative "exceptions"
5
5
 
6
+ # See ActiveRecordWhereAssoc::QueryMethods
6
7
  module ActiveRecordWhereAssoc
8
+ # This module adds new variations of +#where+ to your Models/relations/associations/scopes.
9
+ # These variations check if an association has records, so you can check if a +Post+ has
10
+ # any +Comments+.
11
+ #
12
+ # These variations return a new relation (just like +#where+) so you can chain them with
13
+ # other scoping methods such as +#where+, +#order+, +#limit+, more of these variations, etc.
14
+ #
15
+ # The arguments common to all methods are documented here at the top.
16
+ #
17
+ # For brevity, the examples are all directly on models, such as User, Post, Comment, but
18
+ # the methods are available and behave the same on:
19
+ # * associations: <tt>my_user.posts.where_assoc_exists(:comments)</tt>
20
+ # * relations: <tt>Posts.where(serious: true).where_assoc_exists(:comments)</tt>
21
+ # * scopes: (On the Post model) <tt>scope :with_comments, -> { where_assoc_exists(:comments) }</tt>
22
+ # * models: <tt>Post.where_assoc_exists(:comments)</tt>
23
+ #
24
+ # You may also consider viewing the gem's README. It contains known issues and some tips.
25
+ # You can view the {README on github}[https://github.com/MaxLap/activerecord_where_assoc/blob/master/README.md].
26
+ #
27
+ # If you need extra convincing to try this gem, I have a whole document with the problems of
28
+ # the other ways of doing this kind of filtering:
29
+ # {alternatives' problems}[https://github.com/MaxLap/activerecord_where_assoc/blob/master/ALTERNATIVES_PROBLEMS.md].
30
+ #
31
+ # === Association
32
+ # The associations referred here are the links between your different models. They are your
33
+ # +#belongs_to+, +#has_many+, +#has_one+, +#has_and_belongs_to_many+.
34
+ #
35
+ # This gem is about getting records from your database if their associations match (or don't
36
+ # match) a certain condition (which by default is just to exist).
37
+ #
38
+ # Every method here has an *association_name* parameter. This is the association you want to
39
+ # check if records exists.
40
+ #
41
+ # # Posts with at least one comment
42
+ # Post.where_assoc_exists(:comments)
43
+ #
44
+ # # Posts with no comments
45
+ # Post.where_assoc_not_exists(:comments)
46
+ #
47
+ # If you want, you can pass an array of associations. They will be followed in order, just
48
+ # like a has_many :through would.
49
+ #
50
+ # # Posts which have at least one comment with a reply
51
+ # # In other words: Posts which have at least one reply reachable through his comments
52
+ # Post.where_assoc_exists([:comments, :replies])
53
+ #
54
+ # === Condition
55
+ # After the +association_name+ argument, you can pass additional conditions the associated
56
+ # record must also match to be considered as existing.
57
+ #
58
+ # This +condition+ argument is passed directly to +#where+, so you can pass in the following:
59
+ #
60
+ # # Posts that have at least one comment considered as spam
61
+ # # Using a Hash
62
+ # Post.where_assoc_exists(:comments, is_spam: true)
63
+ #
64
+ # # Using a String
65
+ # Post.where_assoc_exists(:comments, "is_spam = true")
66
+ #
67
+ # # Using an Array (a string and its binds)
68
+ # Post.where_assoc_exists(:comments, ["is_spam = ?", true])
69
+ #
70
+ # If the condition is blank, it is ignored (just like +#where+ does).
71
+ #
72
+ # Note, if you specify multiple associations using an Array, the conditions will only be applied
73
+ # to the last association.
74
+ #
75
+ # # Users which have a post that has a comment marked as spam.
76
+ # # is_spam is only checked on the comment.
77
+ # User.where_assoc_exists([:posts, :comments], is_spam: true)
78
+ #
79
+ # If you want something else, you will need to use a block (see below) to nest multiple calls.
80
+ #
81
+ # # Users which have a post made in the last 5 days which has comments
82
+ # User.where_assoc_exists(:posts) {
83
+ # where("created_at > ?", 5.days.ago).where_assoc_exists(:comments)
84
+ # }
85
+ #
86
+ # === Block
87
+ # The block is used to add more complex conditions. The effect is the same as the condition
88
+ # parameter, in that these conditions must be matched for the association to be considered
89
+ # to exist, but lets you use any scoping methods, such as +#where+, +#joins+, nested
90
+ # +#where_assoc_*+, scopes on the model, etc.
91
+ #
92
+ # Note that using +#joins+ might lead to unexpected results when using #where_assoc_count,
93
+ # since if the joins adds rows, it will change the resulting count. It probably makes more
94
+ # sense to, again, use one of the +where_assoc_*+ methods.
95
+ #
96
+ # There are 2 ways of using the block for adding conditions to the association.
97
+ #
98
+ # [A block that receives one argument]
99
+ # The block receives a relation on the target association and return a relation with added
100
+ # filters or may return nil to do nothing.
101
+ #
102
+ # # These are all equivalent. Posts which have a comment marked as spam
103
+ # # Using a where for the added condition
104
+ # Post.where_assoc_exists(:comments) { |comments_scope| comments_scope.where(is_spam: true) }
105
+ #
106
+ # # Applying a scope of the relation
107
+ # Post.where_assoc_exists(:comments) { |comments_scope| comments_scope.spam_flagged }
108
+ #
109
+ # # Applying a scope of the relation, using the &:shortcut for procs
110
+ # Post.where_assoc_exists(:comments, &:spam_flagged)
111
+ #
112
+ # [A block that receives no argument]
113
+ # Instead of receiving the relation as argument, the relation is used as the "self" of
114
+ # the block. Everything else is identical to the block with one argument.
115
+ #
116
+ # # These are all equivalent. Posts which have a comment marked as spam
117
+ # # Using a where for the added condition
118
+ # Post.where_assoc_exists(:comments) { where(is_spam: true) }
119
+ #
120
+ # # Applying a scope of the relation
121
+ # Post.where_assoc_exists(:comments) { spam_flagged }
122
+ #
123
+ # The main reason to use a block with an argument instead of without one is when you need
124
+ # to call methods on the self outside of the block, such as:
125
+ #
126
+ # Post.where_assoc_exists(:comments) { |comments| comments.where(author_id: foo(:bar)) }
127
+ # Post.where_assoc_exists(:comments) { |comments| comments.where(author_id: self.foo(:bar)) }
128
+ # # In both cases, using the version without arguments would not work, since the #foo
129
+ # # would be called on the scope that was given to the block, instead of on the caller
130
+ # # of the #where_assoc_exists method.
131
+ #
132
+ # # THESE ARE WRONG!
133
+ # Post.where_assoc_exists(:comments) { where(author_id: foo(:bar)) }
134
+ # Post.where_assoc_exists(:comments) { where(author_id: self.foo(:bar)) }
135
+ # # THESE ARE WRONG!
136
+ #
137
+ # === Options
138
+ # Some options are available to tweak how queries are generated. The default values of the options
139
+ # can be changed globally:
140
+ #
141
+ # # Somewhere in your setup code, such as an initializer in Rails
142
+ # ActiveRecordWhereAssoc.default_options[:ignore_limit] = true
143
+ #
144
+ # Or you can pass them as arguments after the +condition+ argument.
145
+ #
146
+ # Post.where_assoc_exists(:comments, "is_spam = TRUE", ignore_limit: true)
147
+ # # Because this is 2 consecutive hashes, must use the +{}+
148
+ # Post.where_assoc_exists(:comments, {is_spam: true}, ignore_limit: true)
149
+ #
150
+ # Note, if you don't need a condition, you must pass nil as condition to provide options:
151
+ # Post.where_assoc_exists(:comments, nil, ignore_limit: true)
152
+ #
153
+ # [ignore_limit]
154
+ # When true, +#limit+ and +#offset+ that are set from default_scope, on associations, and from
155
+ # +#has_one+ are ignored. <br>
156
+ # Removing the limit from +#has_one+ makes them be treated like a +#has_many+.
157
+ #
158
+ # Main reasons to use ignore_limit: true
159
+ # * Needed for MySQL to be able to do anything with +#has_one+ associations because MySQL
160
+ # doesn't support sub-limit. <br>
161
+ # See {MySQL doesn't support limit}[https://github.com/MaxLap/activerecord_where_assoc#mysql-doesnt-support-sub-limit] <br>
162
+ # Note, this does mean the +#has_one+ will be treated as if it was a +#has_many+ for MySQL too.
163
+ # * You have a +#has_one+ association which you know can never have more than one record and are
164
+ # dealing with a heavy/slow query. The query used to deal with +#has_many+ is less complex, and
165
+ # may prove faster.
166
+ # * For this one special case, you want to check the other records that match your has_one
167
+ #
168
+ # [never_alias_limit]
169
+ # When true, +#where_assoc_*+ will not use +#from+ to build relations that have +#limit+ or +#offset+ set
170
+ # on default_scope or on associations or for +#has_one+. <br>
171
+ # This allows changing the from as part of the conditions (such as for a scope)
172
+ #
173
+ # Main reasons to use this: you have to use +#from+ in the block of +#where_assoc_*+ method
174
+ # (ex: because a scope needs +#from+).
175
+ #
176
+ # Why this isn't the default:
177
+ # * From very few tests, the aliasing way seems to produce better plans.
178
+ # * Using aliasing produces a shorter query.
179
+ #
180
+ # [poly_belongs_to]
181
+ # Specify what to do when a polymorphic belongs_to is encountered. Things are tricky because the query can
182
+ # end up searching in multiple Models, and just knowing which ones to look into can require an expensive query.
183
+ # It's also possible that you only want to search for those that match some specific Models, ignoring the other ones.
184
+ # [:pluck]
185
+ # Do a +#pluck+ in the column to detect to possible choices. This option can have a performance cost for big tables
186
+ # or when the query if done often, as the +#pluck+ will be executed each time
187
+ # [model or array of models]
188
+ # Specify which models to search for. This avoids the performance cost of +#pluck+ and can allow to filter some
189
+ # of the choices out that don't interest you. <br>
190
+ # Note, these are not instances, it's actual models, ex: <code>[Post, Comment]</code>
191
+ # [a hash]
192
+ # The keys must be models (same behavior as an array of models). <br>
193
+ # The values are conditions to apply only for key's model.
194
+ # The conditions are either a proc (behaves like the block, but only for that model) or the same things +#where+
195
+ # can receive. (String, Hash, Array, nil). Ex:
196
+ # List.where_assoc_exists(:items, nil, poly_belongs_to: {Car => "color = 'blue'",
197
+ # Computer => proc { brand_new.where(core: 4) } })
198
+ # [:raise]
199
+ # (default) raise an exception when a polymorphic belongs_to is encountered.
7
200
  module QueryMethods
8
- # Returns a new relation, which is the result of filtering the current relation
9
- # based on if a record for the specified association of the model exists. Conditions
10
- # the associated model must match to count as existing can also be specified.
11
- #
12
- # Here is a quick overview of the arguments received followed by a detailed explanation
13
- # along with more examples. You may also consider viewing the gem's README. It contains
14
- # known issues and some tips. The readme is packaged with the gem and viewable on github:
15
- # https://github.com/MaxLap/activerecord_where_assoc
16
- #
201
+ # :section: Basic methods
202
+
203
+ # Returns a new relation with a condition added (a +#where+) that checks if an association
204
+ # of the model exists. Extra conditions the associated model must match can also be specified.
17
205
  #
18
- # As 1st argument, you must specify the association to check against. This can be
19
- # any of the associations on the current relation's model.
206
+ # You could say this is a way of doing a +#select+ that uses associations of your model
207
+ # on the SQL side, but faster and more concise.
20
208
  #
21
- # # Posts that have at least one comment
22
- # Post.where_assoc_exists(:comments)
209
+ # Examples (with an equivalent ruby +#select+)
23
210
  #
24
- # As 2nd argument, you can add conditions that the records in the association must match
25
- # to be considered as existing.
211
+ # # Posts that have comments
212
+ # Post.where_assoc_exists(:comments)
213
+ # Post.all.select { |post| post.comments.exists? }
26
214
  #
27
- # The 3rd argument is for options that alter how the query is generated.
215
+ # # Posts that have comments marked as spam
216
+ # Post.where_assoc_exists(:comments, is_spam: true)
217
+ # Post.select { |post| post.comments.any? {|comment| comment.is_spam } }
28
218
  #
29
- # If your conditions are too complex or too long to be placed in the 2nd argument,
30
- # #where_assoc_* accepts a block in which you can do anything you want on the relation
31
- # (any scoping method such as #where, #joins, nested #where_assoc_*, scopes of the model).
219
+ # # Posts that have comments that have replies
220
+ # Post.where_assoc_exists([:comments, :replies])
221
+ # Post.select { |post| post.comments.any? {|comment| comment.replies.exists? } }
32
222
  #
33
- # === the association argument (1st argument)
223
+ # [association_name]
224
+ # The association that must exist <br>
225
+ # See ActiveRecordWhereAssoc::QueryMethods@Association
34
226
  #
35
- # This is the association you want to check if records exists. If you want, you can pass
36
- # an array of associations. They will be followed in order, just like a has_many :through
37
- # would.
227
+ # [condition]
228
+ # Extra conditions the association must match <br>
229
+ # See ActiveRecordWhereAssoc::QueryMethods@Condition
38
230
  #
39
- # # Posts with at least one comment
40
- # Post.where_assoc_exists(:comments)
231
+ # [options]
232
+ # Options to alter the generated query <br>
233
+ # See ActiveRecordWhereAssoc::QueryMethods@Options
41
234
  #
42
- # # Posts for which there is at least one reply to a comment.
43
- # Post.where_assoc_exists([:comments, :replies])
235
+ # [&block]
236
+ # More complex conditions the associated record must match (can also use scopes of the association's model) <br>
237
+ # See ActiveRecordWhereAssoc::QueryMethods@Block
44
238
  #
45
- # Note that if you use conditions / blocks, they will only be applied to the last
46
- # association of the array. If you want something else, you will need to use
47
- # the block argument to nest multiple calls to #where_assoc_exists
239
+ def where_assoc_exists(association_name, conditions = nil, options = {}, &block)
240
+ ActiveRecordWhereAssoc::CoreLogic.do_where_assoc_exists(self, association_name, conditions, options, &block)
241
+ end
242
+
243
+ # Returns a new relation with a condition added (a +#where+) that checks if an association
244
+ # of the model does not exist. Extra conditions the associated model that exists must not match
245
+ # can also be specified.
48
246
  #
49
- # # Post.where_assoc_exists(:comments) { where_assoc_exists(:replies) }
247
+ # This the exact opposite of what #where_assoc_exists does, so a #where_assoc_not_exists with
248
+ # the same arguments will keep every records that were rejected by the #where_assoc_exists.
50
249
  #
51
- # === the condition argument (2nd argument)
250
+ # You could say this is a way of doing a +#reject+ that uses associations of your model
251
+ # on the SQL side, but faster and more concise.
52
252
  #
53
- # This argument is additional conditions the association's records must fulfill to be
54
- # considered as "existing". The argument is passed directly to #where.
253
+ # Examples (with an equivalent ruby +#reject+)
55
254
  #
56
- # # Posts that have at least one comment considered as spam
57
- # # Using a Hash
58
- # Post.where_assoc_exists(:comments, is_spam: true)
255
+ # # Posts that have no comments
256
+ # Post.where_assoc_not_exists(:comments)
257
+ # Post.all.reject { |post| post.comments.exists? }
59
258
  #
60
- # # Using a String
61
- # Post.where_assoc_exists(:comments, "is_spam = true")
259
+ # # Posts that don't have comments marked as spam (but might have unmarked comments)
260
+ # Post.where_assoc_not_exists(:comments, is_spam: true)
261
+ # Post.reject { |post| post.comments.any? {|comment| comment.is_spam } }
62
262
  #
63
- # # Using an Array (a string and its binds)
64
- # Post.where_assoc_exists(:comments, ["is_spam = ?", true])
263
+ # # Posts that don't have comments that have replies (but can have comments that have no replies)
264
+ # Post.where_assoc_exists([:comments, :replies])
265
+ # Post.reject { |post| post.comments.any? {|comment| comment.replies.exists? } }
65
266
  #
66
- # If the condition argument is blank, it is ignored (just like #where does).
267
+ # [association_name]
268
+ # The association that must exist <br>
269
+ # See ActiveRecordWhereAssoc::QueryMethods@Association
67
270
  #
68
- # === the options argument (3rd argument)
271
+ # [condition]
272
+ # Extra conditions the association must not match <br>
273
+ # See ActiveRecordWhereAssoc::QueryMethods@Condition
69
274
  #
70
- # Some options are available to tweak how things queries are generated. In some case, this
71
- # also changes the results of the query.
275
+ # [options]
276
+ # Options to alter the generated query <br>
277
+ # See ActiveRecordWhereAssoc::QueryMethods@Options
72
278
  #
73
- # ignore_limit: when true, #limit and #offset that are set either from default_scope or
74
- # on associations are ignored. #has_one means #limit(1), so this makes
75
- # #has_one be treated like #has_many.
279
+ # [&block]
280
+ # More complex conditions the associated record must match (can also use scopes of the association's model) <br>
281
+ # See ActiveRecordWhereAssoc::QueryMethods@Block
76
282
  #
77
- # never_alias_limit: when true, #where_assoc_* will not use #from to build relations that
78
- # have #limit or #offset set on default_scope or on associations.
79
- # Note, #has_one means #limit(1), so it will also use #from unless this
80
- # option is activated.
283
+ def where_assoc_not_exists(association_name, conditions = nil, options = {}, &block)
284
+ ActiveRecordWhereAssoc::CoreLogic.do_where_assoc_not_exists(self, association_name, conditions, options, &block)
285
+ end
286
+
287
+ # :section: Complex method
288
+
289
+ # Returns a new relation with a condition added (a +#where+) that checks how many records an association
290
+ # of the model has. Extra conditions the associated model must match can also be specified.
81
291
  #
82
- # === the block
292
+ # This method is a generalization of #where_assoc_exists and #where_assoc_not_exists. It does the same
293
+ # thing, but can be more precise over how many records should exist (and match the extra conditions)
294
+ # To clarify, here are equivalent examples:
83
295
  #
84
- # The block is used to add more complex conditions. The result behaves the same way
85
- # as the 2nd argument's conditions, but lets you use any scoping methods, such as
86
- # #where, #joins, # nested #where_assoc_* and scopes of the model. Note that using
87
- # #joins might lead to unexpected results when using #where_assoc_count, since if
88
- # the joins adds rows, it will change the resulting count.
296
+ # Post.where_assoc_exists(:comments)
297
+ # Post.where_assoc_count(1, :<=, :comments)
89
298
  #
90
- # There are 2 ways of using the block for adding conditions to the association.
299
+ # Post.where_assoc_not_exists(:comments)
300
+ # Post.where_assoc_count(0, :==, :comments)
91
301
  #
92
- # * A block that receives one argument
93
- # The block receives a relation on the target association and return a relation with added
94
- # filters or may return nil to do nothing.
302
+ # But these have no equivalent:
95
303
  #
96
- # # Using a where for the added condition
97
- # Post.where_assoc_exists(:comments) { |comments| comments.where(is_spam: true) }
304
+ # # Posts with at least 5 comments
305
+ # Post.where_assoc_count(5, :<=, :comments)
98
306
  #
99
- # # Applying a scope of the relation
100
- # Post.where_assoc_exists(:comments) { |comments| comments.spam_flagged }
307
+ # # Posts with less than 5 comments
308
+ # Post.where_assoc_count(5, :>, :comments)
101
309
  #
102
- # # Applying a scope of the relation, using the &:shortcut for procs
103
- # Post.where_assoc_exists(:comments, &:spam_flagged)
310
+ # You could say this is a way of doing a +#select+ that +#count+ the associations of your model
311
+ # on the SQL side, but faster and more concise.
104
312
  #
313
+ # Examples (with an equivalent ruby +#select+ and +#count+)
105
314
  #
106
- # * A block that receives no argument
107
- # Instead of receiving the relation as argument, the relation is used as the "self" of
108
- # the block. Everything else is identical to the block with one argument.
315
+ # # Posts with at least 5 comments
316
+ # Post.where_assoc_count(5, :<=, :comments)
317
+ # Post.all.select { |post| post.comments.count >= 5 }
109
318
  #
110
- # # Using a where for the added condition
111
- # Post.where_assoc_exists(:comments) { where(is_spam: true) }
319
+ # # Posts that have at least 5 comments marked as spam
320
+ # Post.where_assoc_count(5, :<=, :comments, is_spam: true)
321
+ # Post.all.select { |post| post.comments.where(is_spam: true).count >= 5 }
112
322
  #
113
- # # Applying a scope of the relation
114
- # Post.where_assoc_exists(:comments) { spam_flagged }
323
+ # # Posts that have at least 10 replies spread over their comments
324
+ # Post.where_assoc_count(10, :<=, [:comments, :replies])
325
+ # Post.select { |post| post.comments.sum { |comment| comment.replies.count } >= 5 }
115
326
  #
116
- # The main reason to use a block with an argument instead of without is when you need
117
- # to call methods on the self outside of the block, such as:
327
+ # [left_operand]
328
+ # 1st argument, the left side of the comparison. <br>
329
+ # One of:
330
+ # * a number
331
+ # * a string of SQL to embed in the query
332
+ # * a range (operator must be :== or :!=), will use BETWEEN or NOT BETWEEN<br>
333
+ # supports infinite ranges and exclusive end
118
334
  #
119
- # Post.where_assoc_exists(:comments) { |comments| comments.where(id: self.something) }
335
+ # # Posts with 5 to 10 comments
336
+ # Post.where_assoc_count(5..10, :==, :comments)
120
337
  #
121
- def where_assoc_exists(association_name, given_scope = nil, options = {}, &block)
122
- ActiveRecordWhereAssoc::CoreLogic.do_where_assoc_exists(self, association_name, given_scope, options, &block)
123
- end
124
-
125
- # Returns a new relation, which is the result of filtering the current relation
126
- # based on if a record for the specified association of the model doesn't exist.
127
- # Conditions the associated model must match to count as existing can also be specified.
128
- #
129
- # The parameters and everything is identical to #where_assoc_exists. The only
130
- # difference is that a record is matched if no matching association record that
131
- # fulfill the conditions are found.
132
- def where_assoc_not_exists(association_name, given_scope = nil, options = {}, &block)
133
- ActiveRecordWhereAssoc::CoreLogic.do_where_assoc_not_exists(self, association_name, given_scope, options, &block)
134
- end
135
-
136
- # Returns a new relation, which is the result of filtering the current relation
137
- # based on how many records for the specified association of the model exists. Conditions
138
- # the associated model must match can also be specified.
338
+ # # Posts with less than 5 or more than 10 comments
339
+ # Post.where_assoc_count(5..10, :!=, :comments)
139
340
  #
140
- # #where_assoc_count is a generalization of #where_assoc_exists and #where_assoc_not_exists.
141
- # It behave behaves the same way as them, but is more flexible as it allows you to be
142
- # specific about how many matches there should be. To clarify, here are equivalent examples:
341
+ # [operator]
342
+ # The operator to use, one of these symbols: <code> :< :<= :== :!= :>= :> </code>
143
343
  #
144
- # Post.where_assoc_exists(:comments)
145
- # Post.where_assoc_count(1, :<=, :comments)
344
+ # [association_name]
345
+ # The association that must exist <br>
346
+ # See ActiveRecordWhereAssoc::QueryMethods@Association
146
347
  #
147
- # Post.where_assoc_not_exists(:comments)
148
- # Post.where_assoc_count(0, :==, :comments)
348
+ # [condition]
349
+ # Extra conditions the association must match to count <br>
350
+ # See ActiveRecordWhereAssoc::QueryMethods@Condition
149
351
  #
150
- # The usage is the same as with #where_assoc_exists, however, 2 arguments are inserted
151
- # at the beginning.
352
+ # [options]
353
+ # Options to alter the generated query <br>
354
+ # See ActiveRecordWhereAssoc::QueryMethods@Options
152
355
  #
153
- # 1st argument: the left side of the comparison. One of:
154
- # a number
155
- # a string of SQL to embed in the query
156
- # a range (operator must be :== or :!=), will use BETWEEN or NOT BETWEEN
157
- # supports infinite ranges and exclusive end
158
- # 2nd argument: the operator to use: :<, :<=, :==, :!=, :>=, :>
159
- # 3rd, 4th and 5th arguments: same as #where_assoc_exists' 1st, 2nd and 3rd arguments
160
- # block: same as #where_assoc_exists' block
356
+ # [&block]
357
+ # More complex conditions the associated record must match (can also use scopes of the association's model) <br>
358
+ # See ActiveRecordWhereAssoc::QueryMethods@Block
161
359
  #
162
360
  # The order of the parameters may seem confusing. But you will get used to it. To help
163
361
  # remember the order of the parameters, remember that the goal is to do:
@@ -168,13 +366,14 @@ module ActiveRecordWhereAssoc
168
366
  # comparing against is the total number of records of that last association.
169
367
  #
170
368
  # # The users that have received at least 5 comments total on all of their posts
171
- # # So this can be one post that has 5 comments of 5 posts with 1 comments
369
+ # # So this can be from one post that has 5 comments of from 5 posts with 1 comments
172
370
  # User.where_assoc_count(5, :<=, [:posts, :comments])
173
371
  #
174
372
  # # The users that have at least 5 posts with at least one comments
175
373
  # User.where_assoc_count(5, :<=, :posts) { where_assoc_exists(:comments) }
176
- def where_assoc_count(left_operand, operator, association_name, given_scope = nil, options = {}, &block)
177
- ActiveRecordWhereAssoc::CoreLogic.do_where_assoc_count(self, left_operand, operator, association_name, given_scope, options, &block)
374
+ #
375
+ def where_assoc_count(left_operand, operator, association_name, conditions = nil, options = {}, &block)
376
+ ActiveRecordWhereAssoc::CoreLogic.do_where_assoc_count(self, left_operand, operator, association_name, conditions, options, &block)
178
377
  end
179
378
  end
180
379
  end