StrictAssociations
What it does
Summary
Enforces explicit definitions of both sides of ActiveRecord associations (e.g. belongs_to, has_many)
StrictAssociations enforces 5 rules:
-
:missing_inverse- Everybelongs_tomust have a correspondinghas_manyorhas_oneon the target model pointing back -
:missing_dependent- Every directhas_manyorhas_onemust declare a:dependentoption (:destroy,:nullify, etc) -
:unregistered_polymorphic- Every polymorphicbelongs_tomust declare:valid_types -
:missing_polymorphic_inverse- Each registered polymorphic type must have ahas_manyorhas_onepointing back -
:habtm_banned- Nohas_and_belongs_to_manyallowed
How to use
Normal case: StrictAssociation enforces doing it right
class Foo < ApplicationRecord
end
class Bar < ApplicationRecord
belongs_to :foo
end
# => StrictAssociation::ViolationError
#
# We failed to define the has_many associationclass Foo < ApplicationRecord
has_many :bars
end
class Bar < ApplicationRecord
belongs_to :foo
end
# => StrictAssociation::ViolationError
#
# We failed to define the :dependent option for the has_many associationclass Foo < ApplicationRecord
has_many :bars, dependent: :destroy
end
class Bar < ApplicationRecord
belongs_to :foo
end
# => GoodIgnore in cases where StrictAssociations don't make sense
# "I know this model doesn't have a has_many pointing back; that's intentional"
belongs_to :foo, strict: false
# "I'm handling dependents manually" (e.g. such as in a callback)
has_many :bars, strict: false
# "I'm purposely not defining the association"
skip_strict_association :barsSample error message
StrictAssociations found 1 violation(s): (StrictAssociations::ViolationError)
Foo.bars [missing_dependent]: Foo#bars is missing a :dependent option.
Add dependent: :destroy, :delete_all, :nullify, or :restrict_with_exception. Or mark
with strict: false. Or call skip_strict_association :bars on Foo.
Polymorphic associations
You must specify valid_types for polymorphic models. These are then also checked
along with other strict associations.
Example
class Role < ActiveRecord::Base
belongs_to :resource, polymorphic: true
end
class Document < ActiveRecord::Base
has_many :roles, dependent: :destroy
end
# => StrictAssociation::ViolationError
# We failed to define :valid_types for the polymorphic belongs_toclass Role < ActiveRecord::Base
belongs_to :resource, polymorphic: true, valid_types: %i[Document Organization]
end
class Document < ActiveRecord::Base
end
# => StrictAssociation::ViolationError
# We failed to define the has_manyclass Role < ActiveRecord::Base
belongs_to :resource, polymorphic: true, valid_types: %i[Document Organization]
end
class Document < ActiveRecord::Base
has_many :roles, dependent: :destroy
end
# => Good