checkpoint before breaking things
This commit is contained in:
134
demo_functionality.rb
Executable file
134
demo_functionality.rb
Executable file
@@ -0,0 +1,134 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require "bundler/setup"
|
||||||
|
require_relative "lib/has_aux_table"
|
||||||
|
Bundler.require(:default, :development)
|
||||||
|
|
||||||
|
ActiveRecord::Base.establish_connection(
|
||||||
|
adapter: "sqlite3",
|
||||||
|
database: ":memory:"
|
||||||
|
)
|
||||||
|
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
||||||
|
|
||||||
|
ActiveRecord::Schema.define do
|
||||||
|
# Create base table and aux table in the same block
|
||||||
|
create_base_table :users do |t|
|
||||||
|
t.create_aux :fa do |t|
|
||||||
|
t.string :username, index: true
|
||||||
|
t.string :url_name, index: true
|
||||||
|
end
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
# Change base table later to add an aux table
|
||||||
|
change_base_table :users do |t|
|
||||||
|
t.create_aux :e621 do |t|
|
||||||
|
t.integer :e621_id, index: true
|
||||||
|
t.string :username, index: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
create_base_table :posts do |t|
|
||||||
|
t.timestamp :posted_at, index: true
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
# Directly create aux tables
|
||||||
|
create_aux_table :posts, :fa do |t|
|
||||||
|
t.references :creator,
|
||||||
|
foreign_key: {
|
||||||
|
to_table: :users_fa_aux,
|
||||||
|
primary_key: :base_table_id
|
||||||
|
}
|
||||||
|
t.integer :fa_id, index: true
|
||||||
|
t.string :title
|
||||||
|
t.string :species
|
||||||
|
end
|
||||||
|
|
||||||
|
create_aux_table :posts, :e621 do |t|
|
||||||
|
t.integer :e621_id, index: true
|
||||||
|
t.string :md5, index: true
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table :user_post_fav_joins, id: false do |t|
|
||||||
|
t.references :user, null: false, foreign_key: { to_table: :users }
|
||||||
|
t.references :post, null: false, foreign_key: { to_table: :posts }
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class UserPostFavJoin < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :post
|
||||||
|
end
|
||||||
|
|
||||||
|
class User < ActiveRecord::Base
|
||||||
|
include HasAuxTable
|
||||||
|
has_many :user_post_fav_joins, dependent: :destroy
|
||||||
|
has_many :favorite_posts, through: :user_post_fav_joins, source: :post
|
||||||
|
has_many :created_posts, class_name: "Post", inverse_of: :creator
|
||||||
|
end
|
||||||
|
|
||||||
|
class FaUser < User
|
||||||
|
aux_table :fa
|
||||||
|
validates :url_name, presence: true
|
||||||
|
has_many :created_posts, class_name: "FaPost", inverse_of: :creator
|
||||||
|
end
|
||||||
|
|
||||||
|
class E621User < User
|
||||||
|
aux_table :e621
|
||||||
|
validates :username, presence: true
|
||||||
|
has_many :created_posts, class_name: "E621Post", inverse_of: :creator
|
||||||
|
end
|
||||||
|
|
||||||
|
class Post < ActiveRecord::Base
|
||||||
|
include HasAuxTable
|
||||||
|
has_many :user_post_fav_joins, dependent: :destroy
|
||||||
|
has_many :favoriting_users, through: :user_post_fav_joins, source: :user
|
||||||
|
validates_presence_of :posted_at
|
||||||
|
end
|
||||||
|
|
||||||
|
class FaPost < Post
|
||||||
|
aux_table :fa
|
||||||
|
belongs_to :creator, class_name: "FaUser", inverse_of: :created_posts
|
||||||
|
validates :fa_id, presence: true, uniqueness: true
|
||||||
|
validates :title, presence: true
|
||||||
|
end
|
||||||
|
|
||||||
|
class E621Post < Post
|
||||||
|
aux_table :e621
|
||||||
|
validates :e621_id, presence: true
|
||||||
|
belongs_to :creator, class_name: "E621User", inverse_of: :created_posts
|
||||||
|
end
|
||||||
|
|
||||||
|
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
||||||
|
|
||||||
|
fa_user = FaUser.create!(username: "Alice", url_name: "alice")
|
||||||
|
|
||||||
|
# puts "Does the post exist? #{FaPost.exists?(fa_id: 1)}"
|
||||||
|
attrs = {
|
||||||
|
# creator_id: fa_user.id,
|
||||||
|
fa_id: 12_345,
|
||||||
|
title: "Test Post",
|
||||||
|
species: "Cat",
|
||||||
|
posted_at: 1.day.ago
|
||||||
|
}
|
||||||
|
fa_post = fa_user.created_posts.create!(attrs)
|
||||||
|
raise unless fa_post.persisted?
|
||||||
|
raise unless fa_post.creator == fa_user
|
||||||
|
raise unless fa_post.creator_id == fa_user.id
|
||||||
|
|
||||||
|
fa_posts_all = FaPost.all.to_a
|
||||||
|
raise unless fa_posts_all.size == 1
|
||||||
|
raise unless fa_posts_all.first.creator == fa_user
|
||||||
|
raise unless fa_posts_all.first.creator_id == fa_user.id
|
||||||
|
|
||||||
|
# e621_user = E621User.create!(username: "bob", e621_id: 67_890)
|
||||||
|
# e621_post =
|
||||||
|
# E621Post.create!(
|
||||||
|
# e621_id: 102_938,
|
||||||
|
# md5: "DEADBEEF" * 4,
|
||||||
|
# posted_at: 2.weeks.ago
|
||||||
|
# )
|
||||||
|
# e621_user.favorite_posts << e621_post
|
||||||
@@ -5,24 +5,13 @@ module HasAuxTable
|
|||||||
module QueryExtensions
|
module QueryExtensions
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
# Get all aux column names for this model
|
|
||||||
def get_aux_column_names(aux_table_name)
|
|
||||||
config = @aux_table_configs[aux_table_name]
|
|
||||||
return [] unless config&.model_class
|
|
||||||
|
|
||||||
config.model_class.column_names.reject do |col|
|
|
||||||
%w[base_table_id created_at updated_at].include?(col)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Split conditions into main table and aux table conditions
|
# Split conditions into main table and aux table conditions
|
||||||
def split_conditions(conditions, association_name)
|
def split_conditions(conditions, aux_config)
|
||||||
aux_columns = self.get_aux_column_names(association_name)
|
|
||||||
main_conditions = {}
|
main_conditions = {}
|
||||||
aux_conditions = {}
|
aux_conditions = {}
|
||||||
|
|
||||||
conditions.each do |key, value|
|
conditions.each do |key, value|
|
||||||
if aux_columns.include?(key.to_s)
|
if aux_config.is_aux_column?(key)
|
||||||
aux_conditions[key] = value
|
aux_conditions[key] = value
|
||||||
else
|
else
|
||||||
main_conditions[key] = value
|
main_conditions[key] = value
|
||||||
@@ -41,6 +30,7 @@ module HasAuxTable
|
|||||||
end
|
end
|
||||||
def setup_query_extensions!(on, aux_config, with_bind_attribute: true)
|
def setup_query_extensions!(on, aux_config, with_bind_attribute: true)
|
||||||
association_name = aux_config.aux_association_name
|
association_name = aux_config.aux_association_name
|
||||||
|
|
||||||
on.define_singleton_method(:where) do |*args|
|
on.define_singleton_method(:where) do |*args|
|
||||||
if args.first.is_a?(Hash)
|
if args.first.is_a?(Hash)
|
||||||
relation = self.eager_load(association_name)
|
relation = self.eager_load(association_name)
|
||||||
@@ -52,6 +42,11 @@ module HasAuxTable
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
all_method = on.method(:all)
|
||||||
|
on.define_singleton_method(:all) do
|
||||||
|
all_method.call.eager_load(association_name)
|
||||||
|
end
|
||||||
|
|
||||||
unscoped_method = on.method(:unscoped)
|
unscoped_method = on.method(:unscoped)
|
||||||
on.define_singleton_method(:unscoped) do
|
on.define_singleton_method(:unscoped) do
|
||||||
relation = unscoped_method.call
|
relation = unscoped_method.call
|
||||||
@@ -62,16 +57,8 @@ module HasAuxTable
|
|||||||
if with_bind_attribute
|
if with_bind_attribute
|
||||||
bind_attribute_method = on.method(:bind_attribute)
|
bind_attribute_method = on.method(:bind_attribute)
|
||||||
on.define_singleton_method(:bind_attribute) do |name, value, &block|
|
on.define_singleton_method(:bind_attribute) do |name, value, &block|
|
||||||
aux_column_names = self.get_aux_column_names(association_name)
|
if aux_config.is_aux_column?(name)
|
||||||
if aux_column_names.include?(name.to_s)
|
aux_config.aux_bind_attribute(name, value, &block)
|
||||||
attr = aux_config.model_class.arel_table[name]
|
|
||||||
bind =
|
|
||||||
aux_config.model_class.predicate_builder.build_bind_attribute(
|
|
||||||
attr.name,
|
|
||||||
value
|
|
||||||
)
|
|
||||||
|
|
||||||
block.call(attr, bind)
|
|
||||||
else
|
else
|
||||||
bind_attribute_method.call(name, value, &block)
|
bind_attribute_method.call(name, value, &block)
|
||||||
end
|
end
|
||||||
@@ -87,7 +74,7 @@ module HasAuxTable
|
|||||||
on.define_singleton_method(:apply_split_conditions!) do |relation, args|
|
on.define_singleton_method(:apply_split_conditions!) do |relation, args|
|
||||||
conditions = args.first
|
conditions = args.first
|
||||||
main_conditions, aux_conditions =
|
main_conditions, aux_conditions =
|
||||||
self.split_conditions(conditions, association_name)
|
self.split_conditions(conditions, aux_config)
|
||||||
relation.where!(main_conditions) if main_conditions.any?
|
relation.where!(main_conditions) if main_conditions.any?
|
||||||
if aux_conditions.any?
|
if aux_conditions.any?
|
||||||
relation.where!(association_name => aux_conditions)
|
relation.where!(association_name => aux_conditions)
|
||||||
@@ -101,7 +88,7 @@ module HasAuxTable
|
|||||||
on.define_singleton_method(:exists?) do |*args|
|
on.define_singleton_method(:exists?) do |*args|
|
||||||
conditions = args.first || {}
|
conditions = args.first || {}
|
||||||
main_conditions, aux_conditions =
|
main_conditions, aux_conditions =
|
||||||
self.split_conditions(conditions, association_name)
|
self.split_conditions(conditions, aux_config)
|
||||||
puts "checking with conditions: #{main_conditions} / #{aux_conditions}"
|
puts "checking with conditions: #{main_conditions} / #{aux_conditions}"
|
||||||
|
|
||||||
relation = self.select("1").joins(association_name)
|
relation = self.select("1").joins(association_name)
|
||||||
|
|||||||
@@ -39,6 +39,21 @@ module HasAuxTable
|
|||||||
aux_association.target ||= aux_association.build
|
aux_association.target ||= aux_association.build
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig do
|
||||||
|
params(name: Symbol, value: T.untyped, block: T.proc.void).returns(
|
||||||
|
Arel::Nodes::Node
|
||||||
|
)
|
||||||
|
end
|
||||||
|
def aux_bind_attribute(name, value, &block)
|
||||||
|
arel_attr = model_class.arel_table[name]
|
||||||
|
aux_bind =
|
||||||
|
model_class.predicate_builder.build_bind_attribute(
|
||||||
|
arel_attr.name,
|
||||||
|
value
|
||||||
|
)
|
||||||
|
block.call(arel_attr, aux_bind)
|
||||||
|
end
|
||||||
|
|
||||||
sig do
|
sig do
|
||||||
params(
|
params(
|
||||||
main_class: T.class_of(ActiveRecord::Base),
|
main_class: T.class_of(ActiveRecord::Base),
|
||||||
@@ -63,6 +78,27 @@ module HasAuxTable
|
|||||||
aux_model = self.ensure_aux_target(main_model)
|
aux_model = self.ensure_aux_target(main_model)
|
||||||
aux_model.assign_attributes(aux_args)
|
aux_model.assign_attributes(aux_args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Array[Symbol]) }
|
||||||
|
def aux_column_names
|
||||||
|
@aux_column_names ||=
|
||||||
|
model_class
|
||||||
|
.column_names
|
||||||
|
.reject do |col|
|
||||||
|
[
|
||||||
|
self.foreign_key,
|
||||||
|
:base_table_id,
|
||||||
|
:created_at,
|
||||||
|
:updated_at
|
||||||
|
].flatten.include?(col.to_sym)
|
||||||
|
end
|
||||||
|
.map(&:to_sym)
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { params(name: T.any(Symbol, String)).returns(T::Boolean) }
|
||||||
|
def is_aux_column?(name)
|
||||||
|
aux_column_names.include?(name.to_sym)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
@@ -173,15 +209,14 @@ module HasAuxTable
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
%i[_read_attribute read_attribute].each do |method_name|
|
%i[_read_attribute read_attribute write_attribute].each do |method_name|
|
||||||
# override _read_attribute to delegate auxiliary columns to the auxiliary table
|
|
||||||
read_attribute_method = self.instance_method(method_name)
|
read_attribute_method = self.instance_method(method_name)
|
||||||
self.define_method(method_name) do |name|
|
self.define_method(method_name) do |name, *args, **kwargs|
|
||||||
if aux_columns_hash.include?(name.to_s)
|
if aux_config.is_aux_column?(name)
|
||||||
target = aux_config.ensure_aux_target(self)
|
target = aux_config.ensure_aux_target(self)
|
||||||
target.send(method_name, name)
|
target.send(method_name, name, *args, **kwargs)
|
||||||
else
|
else
|
||||||
read_attribute_method.bind(self).call(name)
|
read_attribute_method.bind(self).call(name, *args, **kwargs)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -189,8 +224,7 @@ module HasAuxTable
|
|||||||
initialize_method = self.instance_method(:initialize)
|
initialize_method = self.instance_method(:initialize)
|
||||||
self.define_method(:initialize) do |args|
|
self.define_method(:initialize) do |args|
|
||||||
aux_args, main_args =
|
aux_args, main_args =
|
||||||
args.partition { |k, _| aux_columns_hash.key?(k.to_s) }.map(&:to_h)
|
args.partition { |k, _| aux_config.is_aux_column?(k) }.map(&:to_h)
|
||||||
|
|
||||||
initialize_method.bind(self).call(main_args)
|
initialize_method.bind(self).call(main_args)
|
||||||
aux_config.assign_aux_attributes(self, aux_args)
|
aux_config.assign_aux_attributes(self, aux_args)
|
||||||
end
|
end
|
||||||
@@ -208,13 +242,6 @@ module HasAuxTable
|
|||||||
.target
|
.target
|
||||||
.instance_variable_get(:@attributes)
|
.instance_variable_get(:@attributes)
|
||||||
)
|
)
|
||||||
# ActiveRecord::Base.transaction do
|
|
||||||
# aux_model = aux_config.ensure_aux_target(self)
|
|
||||||
# result = reload_method.bind(self).call(*args)
|
|
||||||
# self.send(:"#{aux_config.aux_association_name}=", aux_model)
|
|
||||||
# end
|
|
||||||
# fresh_model =
|
|
||||||
# result
|
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -293,7 +320,8 @@ module HasAuxTable
|
|||||||
class_name: aux_class_name,
|
class_name: aux_class_name,
|
||||||
foreign_key:,
|
foreign_key:,
|
||||||
primary_key:,
|
primary_key:,
|
||||||
inverse_of: main_association_name
|
inverse_of: main_association_name,
|
||||||
|
dependent: :destroy
|
||||||
# autosave: true
|
# autosave: true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ module ::DateAndTime::Zones; end
|
|||||||
module ActiveModel::Error; end
|
module ActiveModel::Error; end
|
||||||
module ActiveRecord::ConnectionAdapters::DatabaseStatements; end
|
module ActiveRecord::ConnectionAdapters::DatabaseStatements; end
|
||||||
module ActiveRecord::ConnectionAdapters::SchemaStatements; end
|
module ActiveRecord::ConnectionAdapters::SchemaStatements; end
|
||||||
module ActiveRecord::ConnectionAdapters::TableDefinition; end
|
|
||||||
module ActiveRecord::Rollback; end
|
module ActiveRecord::Rollback; end
|
||||||
module ActiveRecord::StatementInvalid; end
|
module ActiveRecord::StatementInvalid; end
|
||||||
module ActiveSupport::ArrayInquirer; end
|
module ActiveSupport::ArrayInquirer; end
|
||||||
@@ -18,3 +17,4 @@ module ActiveSupport::Notifications; end
|
|||||||
module ActiveSupport::SafeBuffer; end
|
module ActiveSupport::SafeBuffer; end
|
||||||
module ActiveSupport::StringInquirer; end
|
module ActiveSupport::StringInquirer; end
|
||||||
module ActiveSupport::TimeZone; end
|
module ActiveSupport::TimeZone; end
|
||||||
|
module HasAuxTable::AuxTableConfig::Arel::Nodes::Node; end
|
||||||
|
|||||||
@@ -41,6 +41,38 @@ RSpec.describe HasAuxTable do
|
|||||||
t.string :boat_type
|
t.string :boat_type
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_base_table :people do |t|
|
||||||
|
t.string :name
|
||||||
|
t.timestamps
|
||||||
|
|
||||||
|
t.create_aux :driver do |t|
|
||||||
|
t.references :car,
|
||||||
|
null: false,
|
||||||
|
foreign_key: {
|
||||||
|
to_table: :vehicles_car_aux,
|
||||||
|
primary_key: :base_table_id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
t.create_aux :captain do |t|
|
||||||
|
t.references :boat,
|
||||||
|
null: false,
|
||||||
|
foreign_key: {
|
||||||
|
to_table: :vehicles_boat_aux,
|
||||||
|
primary_key: :base_table_id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
t.create_aux :passenger do |t|
|
||||||
|
t.references :boat,
|
||||||
|
null: false,
|
||||||
|
foreign_key: {
|
||||||
|
to_table: :vehicles_boat_aux,
|
||||||
|
primary_key: :base_table_id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Vehicle < ActiveRecord::Base
|
class Vehicle < ActiveRecord::Base
|
||||||
@@ -49,10 +81,33 @@ RSpec.describe HasAuxTable do
|
|||||||
|
|
||||||
class Car < Vehicle
|
class Car < Vehicle
|
||||||
aux_table :car
|
aux_table :car
|
||||||
|
has_many :drivers, inverse_of: :car
|
||||||
end
|
end
|
||||||
|
|
||||||
class Boat < Vehicle
|
class Boat < Vehicle
|
||||||
aux_table :boat
|
aux_table :boat
|
||||||
|
has_many :passengers, inverse_of: :boat
|
||||||
|
belongs_to :captain, inverse_of: :boat
|
||||||
|
end
|
||||||
|
|
||||||
|
class Person < ActiveRecord::Base
|
||||||
|
include HasAuxTable
|
||||||
|
self.table_name = "people"
|
||||||
|
end
|
||||||
|
|
||||||
|
class Driver < Person
|
||||||
|
aux_table :driver
|
||||||
|
belongs_to :car, inverse_of: :drivers
|
||||||
|
end
|
||||||
|
|
||||||
|
class Captain < Person
|
||||||
|
aux_table :captain
|
||||||
|
has_one :boat, inverse_of: :captain
|
||||||
|
end
|
||||||
|
|
||||||
|
class Passenger < Person
|
||||||
|
aux_table :passenger
|
||||||
|
belongs_to :boat, inverse_of: :passengers
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -558,36 +613,96 @@ RSpec.describe HasAuxTable do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#reload" do
|
describe "methods that depend on relation" do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@car =
|
@car =
|
||||||
Car.create!(name: "Toyota Prius", fuel_type: "hybrid", engine_size: 1.5)
|
Car.create!(name: "Toyota Prius", fuel_type: "hybrid", engine_size: 1.5)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "discards changes to aux attributes when reloading the model" do
|
describe "destroy" do
|
||||||
@car.fuel_type = "gasoline"
|
it "destroys the main record" do
|
||||||
@car.reload
|
expect { @car.destroy }.to change { Car.count }.by(-1)
|
||||||
expect(@car.fuel_type).to eq("hybrid")
|
end
|
||||||
|
|
||||||
|
it "destroys the aux record" do
|
||||||
|
expect { @car.destroy }.to change {
|
||||||
|
Object.const_get(:VehiclesCarAux).count
|
||||||
|
}.by(-1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "discards changes to main attributes when reloading the model" do
|
describe "nested associations" do
|
||||||
@car.name = "Honda Civic"
|
it "can create a driver through the association", skip: true do
|
||||||
@car.reload
|
driver = @car.drivers.create!(name: "John Doe")
|
||||||
expect(@car.name).to eq("Toyota Prius")
|
expect(driver.car).to eq(@car)
|
||||||
|
expect(driver.car_id).to eq(@car.id)
|
||||||
|
expect(driver.car.fuel_type).to eq("hybrid")
|
||||||
|
expect(driver.car.engine_size).to eq(1.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can create a driver directly", skip: true do
|
||||||
|
driver = Driver.create!(car: @car, name: "John Doe")
|
||||||
|
expect(driver.car).to eq(@car)
|
||||||
|
expect(driver.car_id).to eq(@car.id)
|
||||||
|
expect(driver.car.fuel_type).to eq("hybrid")
|
||||||
|
expect(driver.car.engine_size).to eq(1.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can be accessed through the association", skip: true do
|
||||||
|
driver = @car.drivers.create!(name: "John Doe")
|
||||||
|
expect(@car.drivers).to eq([driver])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can be destroyed through the association", skip: true do
|
||||||
|
driver = @car.drivers.build(name: "John Doe")
|
||||||
|
expect { driver.destroy }.to change { @car.drivers.count }.by(-1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can be saved after reloading" do
|
describe "#reload" do
|
||||||
@car.reload
|
it "discards changes to aux attributes when reloading the model" do
|
||||||
@car.name = "Honda Civic"
|
@car.fuel_type = "gasoline"
|
||||||
@car.save!
|
@car.reload
|
||||||
|
expect(@car.fuel_type).to eq("hybrid")
|
||||||
|
end
|
||||||
|
|
||||||
car = Car.find(@car.id)
|
it "discards changes to main attributes when reloading the model" do
|
||||||
expect(car.name).to eq("Honda Civic")
|
@car.name = "Honda Civic"
|
||||||
|
@car.reload
|
||||||
|
expect(@car.name).to eq("Toyota Prius")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can be saved after reloading" do
|
||||||
|
@car.reload
|
||||||
|
@car.name = "Honda Civic"
|
||||||
|
@car.save!
|
||||||
|
|
||||||
|
car = Car.find(@car.id)
|
||||||
|
expect(car.name).to eq("Honda Civic")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reloads with one query" do
|
||||||
|
num_queries = count_queries { @car.reload }
|
||||||
|
expect(num_queries).to eq(1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "reloads with one query" do
|
describe "#exists?" do
|
||||||
num_queries = count_queries { @car.reload }
|
it "works when present with base table attributes" do
|
||||||
expect(num_queries).to eq(1)
|
expect(Car.exists?(id: @car.id)).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "works when missing with with base table attributes" do
|
||||||
|
expect(Car.exists?(id: 9999)).to be_falsey
|
||||||
|
end
|
||||||
|
|
||||||
|
it "works when present with aux table attributes" do
|
||||||
|
expect(Car.exists?(fuel_type: "hybrid")).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "works when missing with aux table attributes" do
|
||||||
|
expect(Car.exists?(fuel_type: "diesel")).to be_falsey
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user