computed_model 0.3 comes with a great number of improvements, and a bunch of breaking changes.
- Breaking changes
include ComputedModelis nowinclude ComputedModel::Model.- Indirect dependencies are now rejected.
computed_model_errorwas removed.dependencybeforedefine_loaderwill be consumed and ignored.dependencybeforedefine_primary_loaderwill be an error.- Cyclic dependency is an error even if it is unused.
nil,true, andfalsein subdeps will be filtered out before passed to a loader.ComputedModel.normalized_dependenciesnow returns[true]instead of[]as an empty value.include_subdepsis nowinclude_subfields
- Notable behavioral changes
- The order in which fields are loaded is changed.
ComputedModel::Modelnow usesActiveSupport::Concern.
- Changed
- Separate
ComputedModel::ModelfromComputedModel#17 - Remove
computed_model_error#18 - Improve behavior around dependency-field pairing #20
- Implement strict field access #23
- Preprocess graph with topological sorting #24
- Implement conditional dependencies and subdependency mapping/passthrough #25
- Use
ActiveSupport::Concern#26 - Rename subdeps as subfields #31
- Separate
- Added
- Refactored
- Misc
See Migration-0.3.md for migration.
New feature: dynamic dependencies
Previously, subdeps are only useful for loaded fields and primary fields. Now computed fields can make use of subdeps!
class User
# Delegate subdeps
dependency(
blog_articles: -> (subdeps) { subdeps }
)
computed def filtered_blog_articles
if current_subfields.normalized[:image].any?
# ...
end
# ...
end
endSee CONCEPTS.md for more usages.
New feature: loader dependency
You can specify dependency from a loaded field.
class User
dependency :raw_user # dependency of :raw_books
define_loader :raw_books, key: -> { id } do |subdeps, **|
# ...
end
endNew feature: computed model inheritance
Now you can reuse computed model definitions via inheritance.
module UserLikeConcern
extends ActiveSupport::Concern
include ComputedModel::Model
dependency :preference, :profile
computed def display_name
"#{preference.title} #{profile.name}"
end
end
class User
include UserLikeConcern
define_loader :preference, key: -> { id } do ... end
define_loader :profile, key: -> { id } do ... end
end
class Admin
include UserLikeConcern
define_loader :preference, key: -> { id } do ... end
define_loader :profile, key: -> { id } do ... end
end