rails/activerecord/test/cases/serialization_test.rb
Sean Griffin 10f75af933 Use bind values for joined tables in where statements
In practical terms, this allows serialized columns and tz aware columns
to be used in wheres that go through joins, where they previously would
not behave correctly. Internally, this removes 1/3 of the cases where we
rely on Arel to perform type casting for us.

There were two non-obvious changes required for this. `update_all` on
relation was merging its bind values with arel's in the wrong order.
Additionally, through associations were assuming there would be no bind
parameters in the preloader (presumably because the where would always
be part of a join)

[Melanie Gilman & Sean Griffin]
2014-11-01 15:39:51 -06:00

105 lines
3.5 KiB
Ruby

require "cases/helper"
require 'models/contact'
require 'models/topic'
require 'models/book'
require 'models/author'
require 'models/post'
class SerializationTest < ActiveRecord::TestCase
fixtures :books
FORMATS = [ :xml, :json ]
def setup
@contact_attributes = {
:name => 'aaron stack',
:age => 25,
:avatar => 'binarydata',
:created_at => Time.utc(2006, 8, 1),
:awesome => false,
:preferences => { :gem => '<strong>ruby</strong>' },
:alternative_id => nil,
:id => nil
}
end
def test_include_root_in_json_is_false_by_default
assert_equal false, ActiveRecord::Base.include_root_in_json, "include_root_in_json should be false by default but was not"
end
def test_serialize_should_be_reversible
FORMATS.each do |format|
@serialized = Contact.new.send("to_#{format}")
contact = Contact.new.send("from_#{format}", @serialized)
assert_equal @contact_attributes.keys.collect(&:to_s).sort, contact.attributes.keys.collect(&:to_s).sort, "For #{format}"
end
end
def test_serialize_should_allow_attribute_only_filtering
FORMATS.each do |format|
@serialized = Contact.new(@contact_attributes).send("to_#{format}", :only => [ :age, :name ])
contact = Contact.new.send("from_#{format}", @serialized)
assert_equal @contact_attributes[:name], contact.name, "For #{format}"
assert_nil contact.avatar, "For #{format}"
end
end
def test_serialize_should_allow_attribute_except_filtering
FORMATS.each do |format|
@serialized = Contact.new(@contact_attributes).send("to_#{format}", :except => [ :age, :name ])
contact = Contact.new.send("from_#{format}", @serialized)
assert_nil contact.name, "For #{format}"
assert_nil contact.age, "For #{format}"
assert_equal @contact_attributes[:awesome], contact.awesome, "For #{format}"
end
end
def test_include_root_in_json_allows_inheritance
original_root_in_json = ActiveRecord::Base.include_root_in_json
ActiveRecord::Base.include_root_in_json = true
klazz = Class.new(ActiveRecord::Base)
klazz.table_name = 'topics'
assert klazz.include_root_in_json
klazz.include_root_in_json = false
assert ActiveRecord::Base.include_root_in_json
assert !klazz.include_root_in_json
assert !klazz.new.include_root_in_json
ensure
ActiveRecord::Base.include_root_in_json = original_root_in_json
end
def test_read_attribute_for_serialization_with_format_without_method_missing
klazz = Class.new(ActiveRecord::Base)
klazz.table_name = 'books'
book = klazz.new
assert_nil book.read_attribute_for_serialization(:format)
end
def test_read_attribute_for_serialization_with_format_after_init
klazz = Class.new(ActiveRecord::Base)
klazz.table_name = 'books'
book = klazz.new(format: 'paperback')
assert_equal 'paperback', book.read_attribute_for_serialization(:format)
end
def test_read_attribute_for_serialization_with_format_after_find
klazz = Class.new(ActiveRecord::Base)
klazz.table_name = 'books'
book = klazz.find(books(:awdr).id)
assert_equal 'paperback', book.read_attribute_for_serialization(:format)
end
def test_find_records_by_serialized_attributes_through_join
author = Author.create!(name: "David")
author.serialized_posts.create!(title: "Hello")
assert_equal 1, Author.joins(:serialized_posts).where(name: "David", serialized_posts: { title: "Hello" }).length
end
end