Class: CompositionItem
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- CompositionItem
- Includes:
- Housekeeping, Shared::IsRender
- Defined in:
- app/models/composition_item.rb
Overview
A CompositionItem is one thing placed in a Composition, for example a block of text in a Template, or a label positioned on a page in a Layout. CompositionItems are Render, not Data.
CompositionItem is not instantiated directly. Subclasses define the units
and meaning of the attributes, and their own uniqueness/constraints.
Subclasses that use composition_id are named
Coordinate system (units are defined by subclasses):
- Left-handed, as CSS: x increases right, y increases down, z increases toward the viewer (higher z is in front, as CSS z-index). Renderers using a right-handed system (e.g. WebGL/three.js) negate y at their boundary.
- The origin is the top-left of the Composition, or of the parent item
when parent_id is set: child coordinates are relative to the parent,
and the parent's rotation and zoom apply to its children (as nested
SVG
transforms), so moving a parent moves its children. - x, y locate the item's top-left corner; width and height extend right and down from there.
- Rotations pivot on the item's center (as the CSS transform-origin default). A positive rotation_z is clockwise as seen by the viewer.
- Stacking: higher z is in front. A nil z is 0. Equal z is broken by id, lower (older) behind, so every renderer paints identically.
- In a Layout only a LayoutItem::GroupItem may be a parent, and groups are translation only, see there.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#composition_id ⇒ Integer?
The Composition, not required (e.g. Label).
-
#composition_item_object_id ⇒ Integer?
Polymorphic id of the thing composed.
-
#composition_item_object_type ⇒ String?
Polymorphic type of the thing composed.
- #css_style ⇒ String?
- #height ⇒ Integer?
- #is_visible ⇒ Boolean?
-
#opacity ⇒ Float?
0..100.
-
#parent_id ⇒ Integer?
The parent CompositionItem, in the same Composition.
-
#position ⇒ Integer
Order among siblings (same composition and parent), see acts_as_list.
-
#project_id ⇒ Integer?
The project ID, nil when the Composition is community.
-
#rotation_z ⇒ Float?
Rotation about the z axis (out of the page), i.e.
-
#svg_clip ⇒ String?
Xml, sensu Depiction.
-
#svg_view_box ⇒ String?
Sensu Depiction.
- #text ⇒ String?
- #total ⇒ Integer?
-
#type ⇒ String
The subclass.
- #width ⇒ Integer?
-
#x ⇒ Float?
Left edge, increases right, see Coordinate system.
-
#y ⇒ Float?
Top edge, increases down, see Coordinate system.
-
#z ⇒ Float?
Increases toward the viewer, see Coordinate system.
- #zoom ⇒ Float?
Class Method Summary collapse
-
.composition_item_object_permitted?(klass) ⇒ Boolean
True if instances of klass may be the composition_item_object.
-
.is_community? ⇒ Boolean
Unify (ApplicationEnumeration.relation_targets_community?) asks this of classes that Data has_many of.
Instance Method Summary collapse
-
#annotates_community_object? ⇒ Boolean
Overrides Housekeeping::Projects so that items of community Compositions are not required to have a project.
-
#community_composition_has_no_object ⇒ Object
protected
Community Compositions reference model attributes, not instance data.
-
#composition_is_unchanged ⇒ Object
protected
Moving an item would leave its children behind, parented across Compositions.
- #composition_item_object_is_permitted ⇒ Object protected
-
#is_community? ⇒ Boolean
Overrides Housekeeping::Projects, which checks the class.
- #parent_is_in_composition ⇒ Object protected
-
#parent_is_not_self_or_descendant ⇒ Object
protected
Also rejects a cycle already in the data above self (and terminates).
-
#set_community_project_id ⇒ Object
protected
Items of a community Composition have no project.
Methods included from Housekeeping
#has_polymorphic_relationship?
Methods inherited from ApplicationRecord
Instance Attribute Details
#composition_id ⇒ Integer?
Returns the Composition, not required (e.g. Label).
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#composition_item_object_id ⇒ Integer?
Returns polymorphic id of the thing composed.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#composition_item_object_type ⇒ String?
Returns polymorphic type of the thing composed.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#css_style ⇒ String?
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#height ⇒ Integer?
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#is_visible ⇒ Boolean?
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#opacity ⇒ Float?
Returns 0..100.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#parent_id ⇒ Integer?
Returns the parent CompositionItem, in the same Composition.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#position ⇒ Integer
Returns order among siblings (same composition and parent), see acts_as_list.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#project_id ⇒ Integer?
Returns the project ID, nil when the Composition is community.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#rotation_z ⇒ Float?
Returns rotation about the z axis (out of the page), i.e. flat, in-plane rotation, see Coordinate system and e.g. CSS rotateZ().
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#svg_clip ⇒ String?
Returns xml, sensu Depiction.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#svg_view_box ⇒ String?
Returns sensu Depiction.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#text ⇒ String?
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#total ⇒ Integer?
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#type ⇒ String
Returns the subclass.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#width ⇒ Integer?
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#x ⇒ Float?
Returns left edge, increases right, see Coordinate system.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#y ⇒ Float?
Returns top edge, increases down, see Coordinate system.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#z ⇒ Float?
Returns increases toward the viewer, see Coordinate system.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
#zoom ⇒ Float?
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/models/composition_item.rb', line 106 class CompositionItem < ApplicationRecord include Housekeeping include Shared::IsRender acts_as_list scope: [:project_id, :composition_id, :parent_id] before_validation :set_community_project_id belongs_to :composition, inverse_of: :composition_items belongs_to :composition_item_object, polymorphic: true belongs_to :parent, class_name: 'CompositionItem', inverse_of: :children has_many :children, class_name: 'CompositionItem', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy validates_presence_of :type validates :opacity, numericality: { in: 0..100 }, allow_nil: true validate :composition_is_unchanged, on: :update validate :parent_is_in_composition validate :parent_is_not_self_or_descendant, if: :parent_id_changed? validate :community_composition_has_no_object validate :composition_item_object_is_permitted # @return [Boolean] # Unify (ApplicationEnumeration.relation_targets_community?) asks this # of classes that Data has_many of. Items that reference objects are # never community, see #community_composition_has_no_object. def self.is_community? false end # @return [Boolean] # true if instances of klass may be the composition_item_object. # Abstract: no objects are permitted unless a subclass says so. def self.composition_item_object_permitted?(klass) false end # @return [Boolean] # overrides Housekeeping::Projects, which checks the class. Per record, # follows the Composition, see Composition#is_community? def is_community? composition&.is_community? ? true : false end # @return [Boolean] # overrides Housekeeping::Projects so that items of community # Compositions are not required to have a project def annotates_community_object? is_community? end protected # Items of a community Composition have no project. def set_community_project_id self.project_id = nil if is_community? end # Moving an item would leave its children behind, parented across # Compositions. def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end # Also rejects a cycle already in the data above self (and terminates). def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end # Community Compositions reference model attributes, not instance data. def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end end |
Class Method Details
.composition_item_object_permitted?(klass) ⇒ Boolean
Returns true if instances of klass may be the composition_item_object. Abstract: no objects are permitted unless a subclass says so.
140 141 142 |
# File 'app/models/composition_item.rb', line 140 def self.composition_item_object_permitted?(klass) false end |
.is_community? ⇒ Boolean
Returns Unify (ApplicationEnumeration.relation_targets_community?) asks this of classes that Data has_many of. Items that reference objects are never community, see #community_composition_has_no_object.
133 134 135 |
# File 'app/models/composition_item.rb', line 133 def self.is_community? false end |
Instance Method Details
#annotates_community_object? ⇒ Boolean
Returns overrides Housekeeping::Projects so that items of community Compositions are not required to have a project.
154 155 156 |
# File 'app/models/composition_item.rb', line 154 def annotates_community_object? is_community? end |
#community_composition_has_no_object ⇒ Object (protected)
Community Compositions reference model attributes, not instance data.
203 204 205 206 207 |
# File 'app/models/composition_item.rb', line 203 def community_composition_has_no_object if is_community? && composition_item_object_id.present? errors.add(:composition_item_object, 'is not permitted in a community composition') end end |
#composition_is_unchanged ⇒ Object (protected)
Moving an item would leave its children behind, parented across Compositions.
167 168 169 170 171 |
# File 'app/models/composition_item.rb', line 167 def composition_is_unchanged if composition_id_changed? errors.add(:composition, 'may not be changed') end end |
#composition_item_object_is_permitted ⇒ Object (protected)
193 194 195 196 197 198 199 200 |
# File 'app/models/composition_item.rb', line 193 def composition_item_object_is_permitted if composition_item_object && !self.class.composition_item_object_permitted?( composition_item_object.class ) errors.add(:composition_item_object_type, 'is not permitted') end end |
#is_community? ⇒ Boolean
Returns overrides Housekeeping::Projects, which checks the class. Per record, follows the Composition, see Composition#is_community?.
147 148 149 |
# File 'app/models/composition_item.rb', line 147 def is_community? composition&.is_community? ? true : false end |
#parent_is_in_composition ⇒ Object (protected)
173 174 175 176 177 |
# File 'app/models/composition_item.rb', line 173 def parent_is_in_composition if parent && parent.composition_id != composition_id errors.add(:parent, 'must be in the same composition') end end |
#parent_is_not_self_or_descendant ⇒ Object (protected)
Also rejects a cycle already in the data above self (and terminates).
180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'app/models/composition_item.rb', line 180 def parent_is_not_self_or_descendant seen = [id] # may be [nil], which is harmless pid = parent_id while pid if seen.include?(pid) errors.add(:parent, 'would create a cycle') return end seen.push(pid) pid = CompositionItem.where(id: pid).pick(:parent_id) end end |
#set_community_project_id ⇒ Object (protected)
Items of a community Composition have no project.
161 162 163 |
# File 'app/models/composition_item.rb', line 161 def set_community_project_id self.project_id = nil if is_community? end |