@@ -1935,6 +1935,61 @@ SELECT books.* FROM books WHERE books.out_of_print = true
1935
1935
1936
1936
[ `unscoped` ] : https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html#method-i-unscoped
1937
1937
1938
+ ### New Chains Inside Scope Block
1939
+
1940
+ Unlike class methods, [ ` scope ` ] [ ] can easily start a new clean chain against the
1941
+ model it is defined on.
1942
+
1943
+ ``` ruby
1944
+ class Topic < ApplicationRecord
1945
+ scope :toplevel , -> { where(parent_id: nil ) }
1946
+ scope :children , -> { where.not(parent_id: nil ) }
1947
+ scope :has_children , -> {
1948
+ where(id: Topic .children.select (:parent_id ))
1949
+ }
1950
+ end
1951
+
1952
+ Topic .toplevel.has_children
1953
+ ```
1954
+
1955
+ Inside ` has_children ` the ` Topic ` chain generates a subquery like this:
1956
+
1957
+ ``` sql
1958
+ SELECT " topics" ." parent_id" FROM " topics" WHERE " topics" ." parent_id" IS NOT NULL
1959
+ ```
1960
+
1961
+ Class methods have different behavior which can be surprising if you expect them
1962
+ to work exactly like scopes.
1963
+
1964
+ ``` ruby
1965
+ class Topic < ApplicationRecord
1966
+ def self .toplevel
1967
+ where(parent_id: nil )
1968
+ end
1969
+
1970
+ def self .children
1971
+ where.not(parent_id: nil )
1972
+ end
1973
+
1974
+ def self .has_children
1975
+ where(id: Topic .children.select (:parent_id ))
1976
+ end
1977
+ end
1978
+
1979
+ Topic .toplevel.has_children
1980
+ ```
1981
+
1982
+ ` Topic ` inside ` has_children ` will implicitly include ` toplevel ` from the outer
1983
+ chain resulting in a subquery of:
1984
+
1985
+ ``` sql
1986
+ SELECT " topics" ." parent_id" FROM " topics" WHERE " topics" ." parent_id" IS NULL AND " topics" ." parent_id" IS NOT NULL
1987
+ ```
1988
+
1989
+ NOTE: In class methods, ` self ` refers back to the model. In scope, ` self ` acts as
1990
+ a chained relation. For the example above, ` self ` and ` Topic ` are interchangeable
1991
+ within the class method definition.
1992
+
1938
1993
Dynamic Finders
1939
1994
---------------
1940
1995
0 commit comments