class ReflectionTest

Public Instance Methods

setup() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 36
def setup
  @first = Topic.find(1)
end
test_active_record_primary_key() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 359
def test_active_record_primary_key
  assert_equal "nick", Subscriber.reflect_on_association(:subscriptions).active_record_primary_key.to_s
  assert_equal "name", Author.reflect_on_association(:essay).active_record_primary_key.to_s
end
test_active_record_primary_key_raises_when_missing_primary_key() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 364
def test_active_record_primary_key_raises_when_missing_primary_key
  reflection = ActiveRecord::Reflection.create(:has_many, :author, nil, {}, Edge)
  assert_raises(ActiveRecord::UnknownPrimaryKey) { reflection.active_record_primary_key }
end
test_aggregation_reflection() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 125
def test_aggregation_reflection
  reflection_for_address = AggregateReflection.new(
    :address, nil, { mapping: [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer
  )

  reflection_for_balance = AggregateReflection.new(
    :balance, nil, { class_name: "Money", mapping: %w(balance amount) }, Customer
  )

  reflection_for_gps_location = AggregateReflection.new(
    :gps_location, nil, {}, Customer
  )

  assert_includes Customer.reflect_on_all_aggregations, reflection_for_gps_location
  assert_includes Customer.reflect_on_all_aggregations, reflection_for_balance
  assert_includes Customer.reflect_on_all_aggregations, reflection_for_address

  assert_equal reflection_for_address, Customer.reflect_on_aggregation(:address)

  assert_equal Address, Customer.reflect_on_aggregation(:address).klass

  assert_equal Money, Customer.reflect_on_aggregation(:balance).klass
end
test_always_validate_association_if_explicit() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 389
def test_always_validate_association_if_explicit
  assert ActiveRecord::Reflection.create(:has_one, :client, nil, { validate: true }, Firm).validate?
  assert ActiveRecord::Reflection.create(:belongs_to, :client, nil, { validate: true }, Firm).validate?
  assert ActiveRecord::Reflection.create(:has_many, :clients, nil, { validate: true }, Firm).validate?
end
test_association_primary_key() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 328
def test_association_primary_key
  # Normal association
  assert_equal "id",   Author.reflect_on_association(:posts).association_primary_key.to_s
  assert_equal "name", Author.reflect_on_association(:essay).association_primary_key.to_s
  assert_equal "name", Essay.reflect_on_association(:writer).association_primary_key.to_s

  # Through association (uses the :primary_key option from the source reflection)
  assert_equal "nick", Author.reflect_on_association(:subscribers).association_primary_key.to_s
  assert_equal "name", Author.reflect_on_association(:essay_category).association_primary_key.to_s
  assert_equal "custom_primary_key", Author.reflect_on_association(:tags_with_primary_key).association_primary_key.to_s # nested
end
test_association_primary_key_raises_when_missing_primary_key() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 349
def test_association_primary_key_raises_when_missing_primary_key
  reflection = ActiveRecord::Reflection.create(:has_many, :edge, nil, {}, Author)
  assert_raises(ActiveRecord::UnknownPrimaryKey) { reflection.association_primary_key }

  through = Class.new(ActiveRecord::Reflection::ThroughReflection) {
    define_method(:source_reflection) { reflection }
  }.new(reflection)
  assert_raises(ActiveRecord::UnknownPrimaryKey) { through.association_primary_key }
end
test_association_primary_key_type() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 340
def test_association_primary_key_type
  # Normal Association
  assert_equal :integer, Author.reflect_on_association(:posts).association_primary_key_type.type
  assert_equal :string,  Author.reflect_on_association(:essay).association_primary_key_type.type

  # Through Association
  assert_equal :string, Author.reflect_on_association(:essay_category).association_primary_key_type.type
end
test_association_reflection_in_modules() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 187
def test_association_reflection_in_modules
  ActiveRecord::Base.store_full_sti_class = false

  assert_reflection MyApplication::Business::Firm,
    :clients_of_firm,
    klass: MyApplication::Business::Client,
    class_name: "Client",
    table_name: "companies"

  assert_reflection MyApplication::Billing::Account,
    :firm,
    klass: MyApplication::Business::Firm,
    class_name: "MyApplication::Business::Firm",
    table_name: "companies"

  assert_reflection MyApplication::Billing::Account,
    :qualified_billing_firm,
    klass: MyApplication::Billing::Firm,
    class_name: "MyApplication::Billing::Firm",
    table_name: "companies"

  assert_reflection MyApplication::Billing::Account,
    :unqualified_billing_firm,
    klass: MyApplication::Billing::Firm,
    class_name: "Firm",
    table_name: "companies"

  assert_reflection MyApplication::Billing::Account,
    :nested_qualified_billing_firm,
    klass: MyApplication::Billing::Nested::Firm,
    class_name: "MyApplication::Billing::Nested::Firm",
    table_name: "companies"

  assert_reflection MyApplication::Billing::Account,
    :nested_unqualified_billing_firm,
    klass: MyApplication::Billing::Nested::Firm,
    class_name: "Nested::Firm",
    table_name: "companies"
ensure
  ActiveRecord::Base.store_full_sti_class = true
end
test_belongs_to_inferred_foreign_key_from_assoc_name() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 178
def test_belongs_to_inferred_foreign_key_from_assoc_name
  Company.belongs_to :foo
  assert_equal "foo_id", Company.reflect_on_association(:foo).foreign_key
  Company.belongs_to :bar, class_name: "Xyzzy"
  assert_equal "bar_id", Company.reflect_on_association(:bar).foreign_key
  Company.belongs_to :baz, class_name: "Xyzzy", foreign_key: "xyzzy_id"
  assert_equal "xyzzy_id", Company.reflect_on_association(:baz).foreign_key
end
test_chain() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 246
def test_chain
  expected = [
    Organization.reflect_on_association(:author_essay_categories),
    Author.reflect_on_association(:essays),
    Organization.reflect_on_association(:authors)
  ]
  actual = Organization.reflect_on_association(:author_essay_categories).chain

  assert_equal expected, actual
end
test_class_for_class_name() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 428
def test_class_for_class_name
  assert_deprecated do
    assert_predicate ActiveRecord::Reflection.create(:has_many, :clients, nil, { class_name: Client }, Firm), :validate?
  end
end
test_collection_association() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 374
def test_collection_association
  assert Pirate.reflect_on_association(:birds).collection?
  assert Pirate.reflect_on_association(:parrots).collection?

  assert !Pirate.reflect_on_association(:ship).collection?
  assert !Ship.reflect_on_association(:pirate).collection?
end
test_column_null_not_null() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 73
def test_column_null_not_null
  subscriber = Subscriber.first
  assert subscriber.column_for_attribute("name").null
  assert !subscriber.column_for_attribute("nick").null
end
test_column_string_type_and_limit() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 68
def test_column_string_type_and_limit
  assert_equal :string, @first.column_for_attribute("title").type
  assert_equal 250, @first.column_for_attribute("title").limit
end
test_columns() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 52
def test_columns
  assert_equal 18, Topic.columns.length
end
test_columns_are_returned_in_the_order_they_were_declared() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 56
def test_columns_are_returned_in_the_order_they_were_declared
  column_names = Topic.columns.map(&:name)
  assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content important approved replies_count unique_replies_count parent_id parent_title type group created_at updated_at), column_names
end
test_content_columns() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 61
def test_content_columns
  content_columns        = Topic.content_columns
  content_column_names   = content_columns.map(&:name)
  assert_equal 13, content_columns.length
  assert_equal %w(title author_name author_email_address written_on bonus_time last_read content important group approved parent_title created_at updated_at).sort, content_column_names.sort
end
test_default_association_validation() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 382
def test_default_association_validation
  assert ActiveRecord::Reflection.create(:has_many, :clients, nil, {}, Firm).validate?

  assert !ActiveRecord::Reflection.create(:has_one, :client, nil, {}, Firm).validate?
  assert !ActiveRecord::Reflection.create(:belongs_to, :client, nil, {}, Firm).validate?
end
test_foreign_key() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 407
def test_foreign_key
  assert_equal "author_id", Author.reflect_on_association(:posts).foreign_key.to_s
  assert_equal "category_id", Post.reflect_on_association(:categorizations).foreign_key.to_s
end
test_foreign_type() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 369
def test_foreign_type
  assert_equal "sponsorable_type", Sponsor.reflect_on_association(:sponsorable).foreign_type.to_s
  assert_equal "sponsorable_type", Sponsor.reflect_on_association(:thing).foreign_type.to_s
end
test_has_and_belongs_to_many_reflection() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 237
def test_has_and_belongs_to_many_reflection
  assert_equal :has_and_belongs_to_many, Category.reflections["posts"].macro
  assert_equal :posts, Category.reflect_on_all_associations(:has_and_belongs_to_many).first.name
end
test_has_many_reflection() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 158
def test_has_many_reflection
  reflection_for_clients = ActiveRecord::Reflection.create(:has_many, :clients, nil, { order: "id", dependent: :destroy }, Firm)

  assert_equal reflection_for_clients, Firm.reflect_on_association(:clients)

  assert_equal Client, Firm.reflect_on_association(:clients).klass
  assert_equal "companies", Firm.reflect_on_association(:clients).table_name

  assert_equal Client, Firm.reflect_on_association(:clients_of_firm).klass
  assert_equal "companies", Firm.reflect_on_association(:clients_of_firm).table_name
end
test_has_many_through_reflection() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 242
def test_has_many_through_reflection
  assert_kind_of ThroughReflection, Subscriber.reflect_on_association(:books)
end
test_has_one_reflection() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 170
def test_has_one_reflection
  reflection_for_account = ActiveRecord::Reflection.create(:has_one, :account, nil, { foreign_key: "firm_id", dependent: :destroy }, Firm)
  assert_equal reflection_for_account, Firm.reflect_on_association(:account)

  assert_equal Account, Firm.reflect_on_association(:account).klass
  assert_equal "accounts", Firm.reflect_on_association(:account).table_name
end
test_human_name() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 40
def test_human_name
  assert_equal "Price estimate", PriceEstimate.model_name.human
  assert_equal "Subscriber", Subscriber.model_name.human
end
test_human_name_for_column() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 79
def test_human_name_for_column
  assert_equal "Author name", @first.column_for_attribute("author_name").human_name
end
test_includes_accepts_strings() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 504
def test_includes_accepts_strings
  hotel = Hotel.create!
  department = hotel.departments.create!
  department.chefs.create!

  assert_nothing_raised do
    assert_equal department.chefs, Hotel.includes(["departments" => "chefs"]).first.chefs
  end
end
test_includes_accepts_symbols() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 494
def test_includes_accepts_symbols
  hotel = Hotel.create!
  department = hotel.departments.create!
  department.chefs.create!

  assert_nothing_raised do
    assert_equal department.chefs, Hotel.includes([departments: :chefs]).first.chefs
  end
end
test_integer_columns() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 83
def test_integer_columns
  assert_equal :integer, @first.column_for_attribute("id").type
end
test_irregular_reflection_class_name() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 117
def test_irregular_reflection_class_name
  ActiveSupport::Inflector.inflections do |inflect|
    inflect.irregular "plural_irregular", "plurales_irregulares"
  end
  reflection = ActiveRecord::Reflection.create(:has_many, "plurales_irregulares", nil, {}, ActiveRecord::Base)
  assert_equal "PluralIrregular", reflection.class_name
end
test_join_table() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 434
def test_join_table
  category = Struct.new(:table_name, :pluralize_table_names).new("categories", true)
  product = Struct.new(:table_name, :pluralize_table_names).new("products", true)

  reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, {}, product)
  reflection.stub(:klass, category) do
    assert_equal "categories_products", reflection.join_table
  end

  reflection = ActiveRecord::Reflection.create(:has_many, :products, nil, {}, category)
  reflection.stub(:klass, product) do
    assert_equal "categories_products", reflection.join_table
  end
end
test_join_table_can_be_overridden() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 479
def test_join_table_can_be_overridden
  category = Struct.new(:table_name, :pluralize_table_names).new("categories", true)
  product = Struct.new(:table_name, :pluralize_table_names).new("products", true)

  reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, { join_table: "product_categories" }, product)
  reflection.stub(:klass, category) do
    assert_equal "product_categories", reflection.join_table
  end

  reflection = ActiveRecord::Reflection.create(:has_many, :products, nil, { join_table: "product_categories" }, category)
  reflection.stub(:klass, product) do
    assert_equal "product_categories", reflection.join_table
  end
end
test_join_table_with_common_prefix() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 449
def test_join_table_with_common_prefix
  category = Struct.new(:table_name, :pluralize_table_names).new("catalog_categories", true)
  product = Struct.new(:table_name, :pluralize_table_names).new("catalog_products", true)

  reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, {}, product)
  reflection.stub(:klass, category) do
    assert_equal "catalog_categories_products", reflection.join_table
  end

  reflection = ActiveRecord::Reflection.create(:has_many, :products, nil, {}, category)
  reflection.stub(:klass, product) do
    assert_equal "catalog_categories_products", reflection.join_table
  end
end
test_join_table_with_different_prefix() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 464
def test_join_table_with_different_prefix
  category = Struct.new(:table_name, :pluralize_table_names).new("catalog_categories", true)
  page = Struct.new(:table_name, :pluralize_table_names).new("content_pages", true)

  reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, {}, page)
  reflection.stub(:klass, category) do
    assert_equal "catalog_categories_content_pages", reflection.join_table
  end

  reflection = ActiveRecord::Reflection.create(:has_many, :pages, nil, {}, category)
  reflection.stub(:klass, page) do
    assert_equal "catalog_categories_content_pages", reflection.join_table
  end
end
test_nested?() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 319
def test_nested?
  assert !Author.reflect_on_association(:comments).nested?
  assert Author.reflect_on_association(:tags).nested?

  # Only goes :through once, but the through_reflection is a has_and_belongs_to_many, so this is
  # a nested through association
  assert Category.reflect_on_association(:post_comments).nested?
end
test_never_validate_association_if_explicit() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 401
def test_never_validate_association_if_explicit
  assert !ActiveRecord::Reflection.create(:has_one, :client, nil, { autosave: true, validate: false }, Firm).validate?
  assert !ActiveRecord::Reflection.create(:belongs_to, :client, nil, { autosave: true, validate: false }, Firm).validate?
  assert !ActiveRecord::Reflection.create(:has_many, :clients, nil, { autosave: true, validate: false }, Firm).validate?
end
test_non_existent_columns_return_null_object() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 87
def test_non_existent_columns_return_null_object
  column = @first.column_for_attribute("attribute_that_doesnt_exist")
  assert_instance_of ActiveRecord::ConnectionAdapters::NullColumn, column
  assert_equal "attribute_that_doesnt_exist", column.name
  assert_nil column.sql_type
  assert_nil column.type
end
test_non_existent_types_are_identity_types() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 95
def test_non_existent_types_are_identity_types
  type = @first.type_for_attribute("attribute_that_doesnt_exist")
  object = Object.new

  assert_equal object, type.deserialize(object)
  assert_equal object, type.cast(object)
  assert_equal object, type.serialize(object)
end
test_read_attribute_names() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 45
def test_read_attribute_names
  assert_equal(
    %w( id title author_name author_email_address bonus_time written_on last_read content important group approved replies_count unique_replies_count parent_id parent_title type created_at updated_at ).sort,
    @first.attribute_names.sort
  )
end
test_reflect_on_all_autosave_associations() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 149
def test_reflect_on_all_autosave_associations
  expected = Pirate.reflect_on_all_associations.select { |r| r.options[:autosave] }
  received = Pirate.reflect_on_all_autosave_associations

  assert !received.empty?
  assert_not_equal Pirate.reflect_on_all_associations.length, received.length
  assert_equal expected, received
end
test_reflect_on_association_accepts_strings() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 520
def test_reflect_on_association_accepts_strings
  assert_nothing_raised do
    assert_equal Hotel.reflect_on_association("departments").name, :departments
  end
end
test_reflect_on_association_accepts_symbols() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 514
def test_reflect_on_association_accepts_symbols
  assert_nothing_raised do
    assert_equal Hotel.reflect_on_association(:departments).name, :departments
  end
end
test_reflection_klass_for_nested_class_name() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 104
def test_reflection_klass_for_nested_class_name
  reflection = ActiveRecord::Reflection.create(
    :has_many,
    nil,
    nil,
    { class_name: "MyApplication::Business::Company" },
    Customer
  )
  assert_nothing_raised do
    assert_equal MyApplication::Business::Company, reflection.klass
  end
end
test_reflection_should_not_raise_error_when_compared_to_other_object() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 229
def test_reflection_should_not_raise_error_when_compared_to_other_object
  assert_not_equal Object.new, Firm._reflections["clients"]
end
test_reflections_should_return_keys_as_strings() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 233
def test_reflections_should_return_keys_as_strings
  assert Category.reflections.keys.all? { |key| key.is_a? String }, "Model.reflections is expected to return string for keys"
end
test_scope_chain() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 257
def test_scope_chain
  expected = [
    [Tagging.reflect_on_association(:tag).scope, Post.reflect_on_association(:first_blue_tags).scope],
    [Post.reflect_on_association(:first_taggings).scope],
    [Author.reflect_on_association(:misc_posts).scope]
  ]
  actual = assert_deprecated do
    Author.reflect_on_association(:misc_post_first_blue_tags).scope_chain
  end
  assert_equal expected, actual

  expected = [
    [
      Tagging.reflect_on_association(:blue_tag).scope,
      Post.reflect_on_association(:first_blue_tags_2).scope,
      Author.reflect_on_association(:misc_post_first_blue_tags_2).scope
    ],
    [],
    []
  ]
  actual = assert_deprecated do
    Author.reflect_on_association(:misc_post_first_blue_tags_2).scope_chain
  end
  assert_equal expected, actual
end
test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_case() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 283
def test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_case
  @hotel = Hotel.create!
  @department = @hotel.departments.create!
  @department.chefs.create!(employable: CakeDesigner.create!)
  @department.chefs.create!(employable: DrinkDesigner.create!)

  assert_equal 1, @hotel.cake_designers.size
  assert_equal 1, @hotel.drink_designers.size
  assert_equal 2, @hotel.chefs.size
end
test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_case_and_sti() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 294
def test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_case_and_sti
  @hotel = Hotel.create!
  @hotel.mocktail_designers << MocktailDesigner.create!

  assert_equal 1, @hotel.mocktail_designers.size
  assert_equal 1, @hotel.mocktail_designers.count
  assert_equal 1, @hotel.chef_lists.size
end
test_scope_chain_of_polymorphic_association_does_not_leak_into_other_hmt_associations() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 303
def test_scope_chain_of_polymorphic_association_does_not_leak_into_other_hmt_associations
  hotel = Hotel.create!
  department = hotel.departments.create!
  drink = department.chefs.create!(employable: DrinkDesigner.create!)
  Recipe.create!(chef_id: drink.id, hotel_id: hotel.id)

  expected_sql = capture_sql { hotel.recipes.to_a }

  Hotel.reflect_on_association(:recipes).clear_association_scope_cache
  hotel.reload
  hotel.drink_designers.to_a
  loaded_sql = capture_sql { hotel.recipes.to_a }

  assert_equal expected_sql, loaded_sql
end
test_symbol_for_class_name() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 424
def test_symbol_for_class_name
  assert_equal Client, Firm.reflect_on_association(:unsorted_clients_with_symbol).klass
end
test_through_reflection_scope_chain_does_not_modify_other_reflections() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 412
def test_through_reflection_scope_chain_does_not_modify_other_reflections
  orig_conds = assert_deprecated do
    Post.reflect_on_association(:first_blue_tags_2).scope_chain
  end.inspect
  assert_deprecated do
    Author.reflect_on_association(:misc_post_first_blue_tags_2).scope_chain
  end
  assert_equal orig_conds, assert_deprecated {
    Post.reflect_on_association(:first_blue_tags_2).scope_chain
  }.inspect
end
test_validate_association_if_autosave() click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 395
def test_validate_association_if_autosave
  assert ActiveRecord::Reflection.create(:has_one, :client, nil, { autosave: true }, Firm).validate?
  assert ActiveRecord::Reflection.create(:belongs_to, :client, nil, { autosave: true }, Firm).validate?
  assert ActiveRecord::Reflection.create(:has_many, :clients, nil, { autosave: true }, Firm).validate?
end

Private Instance Methods

assert_reflection(klass, association, options) click to toggle source
# File activerecord/test/cases/reflection_test.rb, line 527
def assert_reflection(klass, association, options)
  assert reflection = klass.reflect_on_association(association)
  options.each do |method, value|
    assert_equal(value, reflection.send(method))
  end
end