fix model saving

This commit is contained in:
Dylan Knutson
2025-07-14 07:36:50 +00:00
parent 30b017906f
commit 4933e63f31
4 changed files with 150 additions and 172 deletions

View File

@@ -34,58 +34,31 @@ RSpec.describe ActiveRecord::AuxTable do
t.timestamps
end
create_table :test_classes do |t|
t.string :name
t.timestamps
end
# Auxiliary tables for testing
create_table :test_table do |t|
t.references :test_class,
null: false,
foreign_key: {
to_table: :test_classes
}
t.string :description # Changed from :name to avoid conflict
t.timestamps
end
create_table :car_aux do |t|
t.references :vehicle, null: false, foreign_key: { to_table: :vehicles }
create_aux_table :vehicles, :car do |t|
t.string :fuel_type
t.decimal :engine_size, precision: 3, scale: 1
t.timestamps
end
create_table :boat_aux do |t|
t.references :vehicle, null: false, foreign_key: { to_table: :vehicles }
create_aux_table :vehicles, :boat do |t|
t.string :boat_type
t.timestamps
end
end
# Define Car class after schema is set up
class Vehicle < ActiveRecord::Base
include ActiveRecord::AuxTable
end
class Car < Vehicle
aux_table(:car_aux)
aux_table :vehicles_car_aux
end
class Boat < Vehicle
aux_table(:boat_aux)
aux_table :vehicles_boat_aux
end
end
class TestClass < ActiveRecord::Base
include ActiveRecord::AuxTable
self.table_name = "test_classes"
aux_table(:test_table)
end
class Vehicle < ActiveRecord::Base
include ActiveRecord::AuxTable
self.table_name = "vehicles"
end
# Car class will be defined after schema setup
it "has a version number" do
@@ -104,111 +77,7 @@ RSpec.describe ActiveRecord::AuxTable do
expect(Vehicle.count).to eq(0)
end
describe "module inclusion" do
it "adds class methods to the including class" do
expect(TestClass).to respond_to(:aux_table)
expect(TestClass).to respond_to(:aux_table_configuration)
expect(TestClass).to respond_to(:aux_table_configurations)
end
end
describe "aux_table DSL method" do
describe "auxiliary model class generation" do
it "generates auxiliary model class with proper configuration" do
config = TestClass.aux_table_configuration(:test_table)
# Test model class generation
expect(config.model_class).not_to be_nil
expect(config.model_class.table_name).to eq("test_table")
end
it "creates accessible constant for model class" do
expect(Object.const_defined?("CarAux")).to be true
expect(Object.const_get("CarAux")).to be_a(Class)
expect(Object.const_get("CarAux")).to be < ActiveRecord::Base
end
it "prevents duplicate class name conflicts" do
# Define a constant to simulate conflict
Object.const_set("ConflictAux", Class.new)
expect {
TestClass.aux_table(:conflict_aux) { |t| t.string :name }
}.to raise_error(ArgumentError, "Class ConflictAux already exists")
end
it "defines belongs_to association on auxiliary model class" do
config = Car.aux_table_configuration(:car_aux)
# Verify the association is defined
association = config.model_class.reflect_on_association(:car)
expect(association).to be_present
expect(association.macro).to eq(:belongs_to)
expect(association.class_name).to eq("Car")
expect(association.foreign_key).to eq("vehicle_id")
end
it "sets up correct associations for STI classes" do
# Verify the association uses the base class table for the foreign key
association = Car.reflect_on_association(:car_aux)
expect(association).to be_present
expect(association.macro).to eq(:has_one)
expect(association.class_name).to eq("CarAux")
expect(association.foreign_key).to eq("vehicle_id")
end
end
describe "validation" do
it "raises TypeError for nil table name" do
expect {
TestClass.aux_table(nil) { |t| t.string :name }
}.to raise_error(TypeError)
end
it "raises TypeError for invalid table name type" do
expect {
TestClass.aux_table(123) { |t| t.string :name }
}.to raise_error(TypeError)
end
it "raises ArgumentError for duplicate table definitions" do
expect {
TestClass.aux_table(:test_table) { |t| t.string :description }
}.to raise_error(
ArgumentError,
"Auxiliary table 'test_table' is already defined"
)
end
end
end
describe "database integration" do
it "creates auxiliary model class with database operations and associations" do
config = Car.aux_table_configuration(:car_aux)
# Verify the auxiliary model class is properly configured
expect(config.model_class.column_names).to include(
"fuel_type",
"engine_size",
"vehicle_id"
)
# Test associations work correctly
vehicle =
Vehicle.create!(
type: "Car",
name: "Toyota Camry",
fuel_type: "gasoline",
engine_size: 2.5
)
# Verify the association works
expect(vehicle.car_aux.car).to eq(vehicle)
expect(vehicle.car_aux.car.name).to eq("Toyota Camry")
expect(vehicle.car_aux.fuel_type).to eq("gasoline")
expect(vehicle.car_aux.engine_size).to eq(2.5)
end
it "provides automatic attribute accessors for auxiliary table columns" do
vehicle = Car.create!(name: "Honda Civic")
@@ -240,12 +109,12 @@ RSpec.describe ActiveRecord::AuxTable do
end
it "allows saving the model with auxiliary columns" do
vehicle = Car.create!(name: "Honda Civic")
car = Car.create!(name: "Honda Civic")
num_queries =
count_queries do
vehicle.fuel_type = "hybrid"
vehicle.engine_size = 1.8
vehicle.save!
car.fuel_type = "hybrid"
car.engine_size = 1.8
car.save!
end
expect(num_queries).to eq(1)
end
@@ -254,14 +123,29 @@ RSpec.describe ActiveRecord::AuxTable do
describe "query extensions" do
before do
# Create test data
@car1 = Car.create!(name: "Toyota Prius", type: "Car")
@car1.car_aux.update!(fuel_type: "hybrid", engine_size: 1.8)
@car1 =
Car.create!(
name: "Toyota Prius",
type: "Car",
fuel_type: "hybrid",
engine_size: 1.8
)
@car2 = Car.create!(name: "Honda Civic", type: "Car")
@car2.car_aux.update!(fuel_type: "gasoline", engine_size: 2.0)
@car2 =
Car.create!(
name: "Honda Civic",
type: "Car",
fuel_type: "gasoline",
engine_size: 2.0
)
@car3 = Car.create!(name: "Tesla Model 3", type: "Car")
@car3.car_aux.update!(fuel_type: "electric", engine_size: 0.0)
@car3 =
Car.create!(
name: "Tesla Model 3",
type: "Car",
fuel_type: "electric",
engine_size: 0.0
)
end
describe "find method with automatic joins" do