require 'spec_helper' if ActiveRecord::Base.method_defined?(:changed?) describe "OracleEnhancedAdapter dirty object tracking" do before(:all) do ActiveRecord::Base.establish_connection(CONNECTION_PARAMS) @conn = ActiveRecord::Base.connection @conn.execute "DROP TABLE test_employees" rescue nil @conn.execute "DROP SEQUENCE test_employees_seq" rescue nil @conn.execute <<-SQL CREATE TABLE test_employees ( id NUMBER PRIMARY KEY, first_name VARCHAR2(20), last_name VARCHAR2(25), job_id NUMBER(6,0) NULL, salary NUMBER(8,2), comments CLOB, hire_date DATE ) SQL @conn.execute <<-SQL CREATE SEQUENCE test_employees_seq MINVALUE 1 INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE SQL class TestEmployee < ActiveRecord::Base end end after(:all) do Object.send(:remove_const, "TestEmployee") @conn.execute "DROP TABLE test_employees" @conn.execute "DROP SEQUENCE test_employees_seq" ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!") end it "should not mark empty string (stored as NULL) as changed when reassigning it" do @employee = TestEmployee.create!(:first_name => '') @employee.first_name = '' expect(@employee).not_to be_changed @employee.reload @employee.first_name = '' expect(@employee).not_to be_changed end it "should not mark empty integer (stored as NULL) as changed when reassigning it" do @employee = TestEmployee.create!(:job_id => '') @employee.job_id = '' expect(@employee).not_to be_changed @employee.reload @employee.job_id = '' expect(@employee).not_to be_changed end it "should not mark empty decimal (stored as NULL) as changed when reassigning it" do @employee = TestEmployee.create!(:salary => '') @employee.salary = '' expect(@employee).not_to be_changed @employee.reload @employee.salary = '' expect(@employee).not_to be_changed end it "should not mark empty text (stored as NULL) as changed when reassigning it" do @employee = TestEmployee.create!(:comments => nil) @employee.comments = nil expect(@employee).not_to be_changed @employee.reload @employee.comments = nil expect(@employee).not_to be_changed end it "should not mark empty text (stored as empty_clob()) as changed when reassigning it" do @employee = TestEmployee.create!(:comments => '') @employee.comments = '' expect(@employee).not_to be_changed @employee.reload @employee.comments = '' expect(@employee).not_to be_changed end it "should mark empty text (stored as empty_clob()) as changed when assigning nil to it" do @employee = TestEmployee.create!(:comments => '') @employee.comments = nil expect(@employee).to be_changed @employee.reload @employee.comments = nil expect(@employee).to be_changed end it "should mark empty text (stored as NULL) as changed when assigning '' to it" do @employee = TestEmployee.create!(:comments => nil) @employee.comments = '' expect(@employee).to be_changed @employee.reload @employee.comments = '' expect(@employee).to be_changed end it "should not mark empty date (stored as NULL) as changed when reassigning it" do @employee = TestEmployee.create!(:hire_date => '') @employee.hire_date = '' expect(@employee).not_to be_changed @employee.reload @employee.hire_date = '' expect(@employee).not_to be_changed end it "should not mark integer as changed when reassigning it" do @employee = TestEmployee.new @employee.job_id = 0 expect(@employee.save!).to be_truthy expect(@employee).not_to be_changed @employee.job_id = '0' expect(@employee).not_to be_changed end it "should not update unchanged CLOBs" do @employee = TestEmployee.create!( :comments => "initial" ) expect(@employee.save!).to be_truthy @employee.reload expect(@employee.comments).to eq('initial') oci_conn = @conn.instance_variable_get('@connection') class << oci_conn def write_lob(lob, value, is_binary = false); raise "don't do this'"; end end expect{@employee.save!}.not_to raise_exception(RuntimeError, "don't do this'") class << oci_conn remove_method :write_lob end end it "should be able to handle attributes which are not backed by a column" do TestEmployee.create!(:comments => "initial") @employee = TestEmployee.select("#{TestEmployee.quoted_table_name}.*, 24 ranking").first expect { @employee.ranking = 25 }.to_not raise_error end end end