aboutsummaryrefslogblamecommitdiffstats
path: root/activerecord/test/cases/relation/mutation_test.rb
blob: 11ef0d8743b78070ce10d4242becb159927bef7f (plain) (tree)
1
2
3
4
5
6
7
8
9

                      

                   
                                                     
                                                 


                                                    






                                                 



                                



                           



                                     



                                     


                
                                                                                                

       
                                                                                                                        





                                                                        
                       

                                                     

       


                                                         

       
                                                         






                                                    
                                                                                
                      



                                                 

       
                          
                                                        
                                                       

       
                        









                                                         
                                        



                                                
                                                                                                          





                                                                        


                                                    

       


                                                   

       
                       
                                       
 

                                                      


                                      
                                                           







                                                      

                                                              


                             

                                                                   
 
                             
 

                                                                    

       

                                                               
                                                              

       
                    

                                                           

       
                               
                                                                            

       
                   




                                                            
                       

                                                


       
require "cases/helper"
require "models/post"

module ActiveRecord
  class RelationMutationTest < ActiveRecord::TestCase
    FakeKlass = Struct.new(:table_name, :name) do
      extend ActiveRecord::Delegation::DelegateCache
      inherited self

      def connection
        Post.connection
      end

      def relation_delegate_class(klass)
        self.class.relation_delegate_class(klass)
      end

      def attribute_alias?(name)
        false
      end

      def sanitize_sql(sql)
        sql
      end

      def sanitize_sql_for_order(sql)
        sql
      end

      def arel_attribute(name, table)
        table[name]
      end
    end

    def relation
      @relation ||= Relation.new FakeKlass.new("posts"), Post.arel_table, Post.predicate_builder
    end

    (Relation::MULTI_VALUE_METHODS - [:references, :extending, :order, :unscope, :select, :left_joins]).each do |method|
      test "##{method}!" do
        assert relation.public_send("#{method}!", :foo).equal?(relation)
        assert_equal [:foo], relation.public_send("#{method}_values")
      end
    end

    test "#_select!" do
      assert relation._select!(:foo).equal?(relation)
      assert_equal [:foo], relation.select_values
    end

    test "#order!" do
      assert relation.order!("name ASC").equal?(relation)
      assert_equal ["name ASC"], relation.order_values
    end

    test "#order! with symbol prepends the table name" do
      assert relation.order!(:name).equal?(relation)
      node = relation.order_values.first
      assert node.ascending?
      assert_equal :name, node.expr.name
      assert_equal "posts", node.expr.relation.name
    end

    test "#order! on non-string does not attempt regexp match for references" do
      obj = Object.new
      assert_not_called(obj, :=~) do
        assert relation.order!(obj)
        assert_equal [obj], relation.order_values
      end
    end

    test "#references!" do
      assert relation.references!(:foo).equal?(relation)
      assert_includes relation.references_values, "foo"
    end

    test "extending!" do
      mod, mod2 = Module.new, Module.new

      assert relation.extending!(mod).equal?(relation)
      assert_equal [mod], relation.extending_values
      assert relation.is_a?(mod)

      relation.extending!(mod2)
      assert_equal [mod, mod2], relation.extending_values
    end

    test "extending! with empty args" do
      relation.extending!
      assert_equal [], relation.extending_values
    end

    (Relation::SINGLE_VALUE_METHODS - [:lock, :reordering, :reverse_order, :create_with]).each do |method|
      test "##{method}!" do
        assert relation.public_send("#{method}!", :foo).equal?(relation)
        assert_equal :foo, relation.public_send("#{method}_value")
      end
    end

    test "#from!" do
      assert relation.from!("foo").equal?(relation)
      assert_equal "foo", relation.from_clause.value
    end

    test "#lock!" do
      assert relation.lock!("foo").equal?(relation)
      assert_equal "foo", relation.lock_value
    end

    test "#reorder!" do
      @relation = relation.order("foo")

      assert relation.reorder!("bar").equal?(relation)
      assert_equal ["bar"], relation.order_values
      assert relation.reordering_value
    end

    test "#reorder! with symbol prepends the table name" do
      assert relation.reorder!(:name).equal?(relation)
      node = relation.order_values.first

      assert node.ascending?
      assert_equal :name, node.expr.name
      assert_equal "posts", node.expr.relation.name
    end

    test "reverse_order!" do
      @relation = Post.order("title ASC, comments_count DESC")

      relation.reverse_order!

      assert_equal "title DESC", relation.order_values.first
      assert_equal "comments_count ASC", relation.order_values.last

      relation.reverse_order!

      assert_equal "title ASC", relation.order_values.first
      assert_equal "comments_count DESC", relation.order_values.last
    end

    test "create_with!" do
      assert relation.create_with!(foo: "bar").equal?(relation)
      assert_equal({ foo: "bar" }, relation.create_with_value)
    end

    test "merge!" do
      assert relation.merge!(select: :foo).equal?(relation)
      assert_equal [:foo], relation.select_values
    end

    test "merge with a proc" do
      assert_equal [:foo], relation.merge(-> { select(:foo) }).select_values
    end

    test "none!" do
      assert relation.none!.equal?(relation)
      assert_equal [NullRelation], relation.extending_values
      assert relation.is_a?(NullRelation)
    end

    test "distinct!" do
      relation.distinct! :foo
      assert_equal :foo, relation.distinct_value
    end
  end
end