Skip to content

Commit

Permalink
Merge branch '9.0-stable' into 5836-embedded-callbacks-9.0-stable
Browse files Browse the repository at this point in the history
  • Loading branch information
jamis committed Jan 22, 2025
2 parents d9b0258 + 8eb3123 commit 7d73836
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 3 deletions.
3 changes: 3 additions & 0 deletions lib/mongoid/association/eager_loadable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ def preload(associations, docs)
docs_map = {}
queue = [ klass.to_s ]

# account for single-collection inheritance
queue.push(klass.root_class.to_s) if klass != klass.root_class

while klass = queue.shift
if as = assoc_map.delete(klass)
as.each do |assoc|
Expand Down
12 changes: 12 additions & 0 deletions lib/mongoid/traversable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ def hereditary?
!!(superclass < Mongoid::Document)
end

# Returns the root class of the STI tree that the current
# class participates in. If the class is not an STI subclass, this
# returns the class itself.
#
# @return [ Mongoid::Document ] the root of the STI tree
def root_class
root = self
root = root.superclass while root.hereditary?

root
end

# When inheriting, we want to copy the fields from the parent class and
# set the on the child to start, mimicking the behavior of the old
# class_inheritable_accessor that was deprecated in Rails edge.
Expand Down
2 changes: 1 addition & 1 deletion lib/mongoid/validatable/associated.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def validate_association(document, attribute)
# use map.all? instead of just all?, because all? will do short-circuit
# evaluation and terminate on the first failed validation.
list.map do |value|
if value && !value.flagged_for_destroy? && (!value.persisted? || value.changed?)
if value && !value.flagged_for_destroy?
value.validated? ? true : value.valid?
else
true
Expand Down
26 changes: 24 additions & 2 deletions spec/mongoid/association/eager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,36 @@
Mongoid::Contextual::Mongo.new(criteria)
end

let(:association_host) { Account }

let(:inclusions) do
includes.map do |key|
Account.reflect_on_association(key)
association_host.reflect_on_association(key)
end
end

let(:doc) { criteria.first }

context 'when root is an STI subclass' do
# Driver has_one Vehicle
# Vehicle belongs_to Driver
# Truck is a Vehicle

before do
Driver.create!(vehicle: Truck.new)
end

let(:criteria) { Truck.all }
let(:includes) { %i[ driver ] }
let(:association_host) { Truck }

it 'preloads the driver' do
expect(doc.ivar(:driver)).to be false
context.preload(inclusions, [ doc ])
expect(doc.ivar(:driver)).to be == Driver.first
end
end

context "when belongs_to" do

let!(:account) do
Expand All @@ -43,7 +65,7 @@
it "preloads the parent" do
expect(doc.ivar(:person)).to be false
context.preload(inclusions, [doc])
expect(doc.ivar(:person)).to eq(doc.person)
expect(doc.ivar(:person)).to be == person
end
end

Expand Down
60 changes: 60 additions & 0 deletions spec/mongoid/association_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,66 @@ class AssocationSpecModel
expect(name).to_not be_an_embedded_many
end
end

context "when validation depends on association" do
before(:all) do
class Author
include Mongoid::Document
embeds_many :books, cascade_callbacks: true
field :condition, type: Boolean
end

class Book
include Mongoid::Document
embedded_in :author
validate :parent_condition_is_not_true

def parent_condition_is_not_true
return unless author&.condition
errors.add :base, "Author condition is true."
end
end

Author.delete_all
Book.delete_all
end

let(:author) { Author.new }
let(:book) { Book.new }

context "when author is not persisted" do
it "is valid without books" do
expect(author.valid?).to be true
end

it "is valid with a book" do
author.books << book
expect(author.valid?).to be true
end

it "is not valid when condition is true with a book" do
author.condition = true
author.books << book
expect(author.valid?).to be false
end
end

context "when author is persisted" do
before do
author.books << book
author.save
end

it "remains valid initially" do
expect(author.valid?).to be true
end

it "becomes invalid when condition is set to true" do
author.update_attributes(condition: true)
expect(author.valid?).to be false
end
end
end
end

describe "#embedded_one?" do
Expand Down

0 comments on commit 7d73836

Please sign in to comment.