Module: YamlExporter::Nodes::OfResolution
- Included in:
- ManyReference, ManyThrough, OneReferenceOf
- Defined in:
- lib/yaml_exporter/nodes/of_resolution.rb
Overview
Shared of: navigation for reference nodes that identify their target
indirectly: the YAML value names a column on a related model
(of:) reachable from the target, not on the target itself.
Example: a reviewer target is a CorporateUser, and
CorporateUser belongs_to :user (a User with a slug). Declaring
find_by: :slug, of: :user stores the User's slug in the YAML and, on
import, resolves the User first and then reverses of: back to the
CorporateUser.
Mixed into OneReferenceOf, ManyReference and ManyThrough. The host must
provide target_class and set @find_by and @of (both symbols).
Instance Method Summary collapse
-
#find_target_via(related) ⇒ Object
Navigate from a resolved related record back to the target.
-
#of_class ⇒ Object
The class of the related model (CorporateUser.user -> User).
-
#of_reflection ⇒ Object
The related model that actually carries the find_by column (CorporateUser.user -> User).
-
#of_value_for(target) ⇒ Object
The YAML value for a target: the find_by column on its
of:relation. -
#resolve_target_by_of(value) ⇒ Object
Resolve a single YAML value to a target record: find the related record by find_by, then reverse
of:back to the target. - #singular_of_association?(reflection) ⇒ Boolean
-
#validate_of_reflection!(node_label) ⇒ Object
Declaration-time check:
of:must name a 1:[0,1] association on the target.
Instance Method Details
#find_target_via(related) ⇒ Object
Navigate from a resolved related record back to the target.
belongs_to (:user on CorporateUser): FK is on the target. target_class.find_by(user_id: related.id) has_one (:profile on CorporateUser): FK is on the related record. target_class.find_by(id: related.corporate_user_id)
45 46 47 48 49 50 51 52 53 |
# File 'lib/yaml_exporter/nodes/of_resolution.rb', line 45 def find_target_via() if of_reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) pk_val = .public_send(of_reflection.association_primary_key) target_class.find_by(of_reflection.foreign_key => pk_val) else # has_one fk_val = .public_send(of_reflection.foreign_key) target_class.find_by(of_reflection.association_primary_key => fk_val) end end |
#of_class ⇒ Object
The class of the related model (CorporateUser.user -> User).
25 26 27 |
# File 'lib/yaml_exporter/nodes/of_resolution.rb', line 25 def of_class @of_class ||= of_reflection.klass end |
#of_reflection ⇒ Object
The related model that actually carries the find_by column (CorporateUser.user -> User).
20 21 22 |
# File 'lib/yaml_exporter/nodes/of_resolution.rb', line 20 def of_reflection @of_reflection ||= target_class.reflect_on_association(@of) end |
#of_value_for(target) ⇒ Object
The YAML value for a target: the find_by column on its of: relation.
nil when the target has no related record (can't be represented).
57 58 59 60 |
# File 'lib/yaml_exporter/nodes/of_resolution.rb', line 57 def of_value_for(target) = target.public_send(@of) &.public_send(@find_by) end |
#resolve_target_by_of(value) ⇒ Object
Resolve a single YAML value to a target record: find the related
record by find_by, then reverse of: back to the target. Returns nil
if either lookup misses.
32 33 34 35 36 37 |
# File 'lib/yaml_exporter/nodes/of_resolution.rb', line 32 def resolve_target_by_of(value) = of_class.find_by(@find_by => value) return nil unless find_target_via() end |
#singular_of_association?(reflection) ⇒ Boolean
78 79 80 81 |
# File 'lib/yaml_exporter/nodes/of_resolution.rb', line 78 def singular_of_association?(reflection) reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) || reflection.is_a?(ActiveRecord::Reflection::HasOneReflection) end |
#validate_of_reflection!(node_label) ⇒ Object
Declaration-time check: of: must name a 1:[0,1] association on the
target. Raises ArgumentError at class load otherwise.
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/yaml_exporter/nodes/of_resolution.rb', line 64 def validate_of_reflection!(node_label) of_ref = target_class.reflect_on_association(@of) unless of_ref raise ArgumentError, "`#{node_label}, of: #{@of.inspect}`: #{target_class} has no association `#{@of}`" end return if singular_of_association?(of_ref) raise ArgumentError, "`#{node_label}, of: #{@of.inspect}`: `of:` must be a 1:[0,1] association " \ "(belongs_to or has_one); got #{of_ref.macro}" end |