Class: Composition

Inherits:
ApplicationRecord show all
Includes:
Housekeeping, Shared::IsRender, Shared::Pinnable
Defined in:
app/models/composition.rb

Overview

A Composition is the arrangement of things for rendering, for example a layout of labels on a page. Compositions are Render, not Data.

Composition is not instantiated directly, see Layout and Template.

Direct Known Subclasses

Layout, Template

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Shared::Pinnable

#inserted?, #pinboard_item_for, #pinned?

Methods included from Housekeeping

#has_polymorphic_relationship?

Methods inherited from ApplicationRecord

transaction_with_retry

Instance Attribute Details

#description ⇒ String?

Returns a free text description.

Returns:

  • (String, nil) —

    a free text description



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
# File 'app/models/composition.rb', line 28

class Composition < ApplicationRecord
  include Housekeeping
  include Shared::IsRender
  include Shared::Pinnable

  # Only true or nil
  normalizes :is_community, with: -> (v) { v.presence }

  before_validation :set_community_project_id

  after_save :set_composition_items_project_id, if: :saved_change_to_project_id?

  has_many :composition_items, inverse_of: :composition, dependent: :destroy

  scope :visible_to_project, -> (project_id) {
    where(project_id:).or(where(is_community: true))
  }

  validates_presence_of :type, :name
  validates :name, uniqueness: { scope: [:project_id, :type] }
  validate :is_community_is_permitted
  validate :community_has_no_item_objects

  # @return [Boolean]
  #   true if *some* instances may be shared across projects (compare
  #   IsData's class-level .is_community?, which means *all* instances are).
  #   Subclasses that reference only model attributes and attribute
  #   modifiers, never instance data, may override this.
  def self.community_permitted?
    false
  end

  # @return [Array of Integer]
  #   ids of the Compositions (of this class) visible to the project that
  #   user_id last changed, most recent first. A change to any item counts
  #   as a change to its Composition. Destroyed items leave no trace.
  def self.used_recently(user_id, project_id)
    visible = visible_to_project(project_id)

    own = visible.where(updated_by_id: user_id)
      .select(:id, :updated_at)
    items = CompositionItem
      .where(updated_by_id: user_id, composition_id: visible.select(:id))
      .select('composition_id AS id', :updated_at)

    Composition
      .from("(#{own.to_sql} UNION ALL #{items.to_sql}) AS used")
      .group('used.id')
      .order(Arel.sql('MAX(used.updated_at) DESC'))
      .limit(10)
      .pluck('used.id')
  end

  # @return [Hash]
  #   pinboard, recent (the Compositions the user worked on last, most
  #   recent first) and quick (inserted pins plus the 4 most recent). Call
  #   on a subclass, e.g. Layout::LightTable, for only its Compositions.
  def self.select_optimized(user_id, project_id)
    q = visible_to_project(project_id)
    pinned = q.pinned_by(user_id).pinned_in_project(project_id)

    r = used_recently(user_id, project_id)
    recent = q.where(id: r).to_a.sort_by { |c| r.index(c.id) }

    {
      quick: (pinned.pinboard_inserted.to_a + recent.first(4)).uniq,
      pinboard: pinned.pinboard_ordered.to_a,
      recent:
    }
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects, which checks the class. Per record,
  #   unlike Data where community is a property of the class. There is no
  #   class-level .is_community? here, nothing asks it of Composition.
  def is_community?
    is_community == true
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects so that community records are not
  #   required to have a project
  def annotates_community_object?
    is_community?
  end

  protected

  def is_community_is_permitted
    if is_community? && !self.class.community_permitted?
      errors.add(:is_community, "is not permitted for #{type}")
    end
  end

  # Community Compositions reference model attributes, not instance data.
  def community_has_no_item_objects
    if is_community? && persisted? &&
        composition_items.where.not(composition_item_object_id: nil).exists?
      errors.add(:is_community, 'is not permitted when items reference objects')
    end
  end

  def set_composition_items_project_id
    composition_items.update_all(project_id:)
  end

  def set_community_project_id
    if is_community?
      self.project_id = nil
    else
      self.project_id ||= Current.project_id
    end
  end

end

#is_community ⇒ true?

Returns true when the Composition is shared across all projects, in which case project_id is nil. Only permitted for some subclasses, see .community_permitted?. Never false, false is stored as nil.

Returns:

  • (true, nil) —

    true when the Composition is shared across all projects, in which case project_id is nil. Only permitted for some subclasses, see .community_permitted?. Never false, false is stored as nil.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
# File 'app/models/composition.rb', line 28

class Composition < ApplicationRecord
  include Housekeeping
  include Shared::IsRender
  include Shared::Pinnable

  # Only true or nil
  normalizes :is_community, with: -> (v) { v.presence }

  before_validation :set_community_project_id

  after_save :set_composition_items_project_id, if: :saved_change_to_project_id?

  has_many :composition_items, inverse_of: :composition, dependent: :destroy

  scope :visible_to_project, -> (project_id) {
    where(project_id:).or(where(is_community: true))
  }

  validates_presence_of :type, :name
  validates :name, uniqueness: { scope: [:project_id, :type] }
  validate :is_community_is_permitted
  validate :community_has_no_item_objects

  # @return [Boolean]
  #   true if *some* instances may be shared across projects (compare
  #   IsData's class-level .is_community?, which means *all* instances are).
  #   Subclasses that reference only model attributes and attribute
  #   modifiers, never instance data, may override this.
  def self.community_permitted?
    false
  end

  # @return [Array of Integer]
  #   ids of the Compositions (of this class) visible to the project that
  #   user_id last changed, most recent first. A change to any item counts
  #   as a change to its Composition. Destroyed items leave no trace.
  def self.used_recently(user_id, project_id)
    visible = visible_to_project(project_id)

    own = visible.where(updated_by_id: user_id)
      .select(:id, :updated_at)
    items = CompositionItem
      .where(updated_by_id: user_id, composition_id: visible.select(:id))
      .select('composition_id AS id', :updated_at)

    Composition
      .from("(#{own.to_sql} UNION ALL #{items.to_sql}) AS used")
      .group('used.id')
      .order(Arel.sql('MAX(used.updated_at) DESC'))
      .limit(10)
      .pluck('used.id')
  end

  # @return [Hash]
  #   pinboard, recent (the Compositions the user worked on last, most
  #   recent first) and quick (inserted pins plus the 4 most recent). Call
  #   on a subclass, e.g. Layout::LightTable, for only its Compositions.
  def self.select_optimized(user_id, project_id)
    q = visible_to_project(project_id)
    pinned = q.pinned_by(user_id).pinned_in_project(project_id)

    r = used_recently(user_id, project_id)
    recent = q.where(id: r).to_a.sort_by { |c| r.index(c.id) }

    {
      quick: (pinned.pinboard_inserted.to_a + recent.first(4)).uniq,
      pinboard: pinned.pinboard_ordered.to_a,
      recent:
    }
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects, which checks the class. Per record,
  #   unlike Data where community is a property of the class. There is no
  #   class-level .is_community? here, nothing asks it of Composition.
  def is_community?
    is_community == true
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects so that community records are not
  #   required to have a project
  def annotates_community_object?
    is_community?
  end

  protected

  def is_community_is_permitted
    if is_community? && !self.class.community_permitted?
      errors.add(:is_community, "is not permitted for #{type}")
    end
  end

  # Community Compositions reference model attributes, not instance data.
  def community_has_no_item_objects
    if is_community? && persisted? &&
        composition_items.where.not(composition_item_object_id: nil).exists?
      errors.add(:is_community, 'is not permitted when items reference objects')
    end
  end

  def set_composition_items_project_id
    composition_items.update_all(project_id:)
  end

  def set_community_project_id
    if is_community?
      self.project_id = nil
    else
      self.project_id ||= Current.project_id
    end
  end

end

#name ⇒ String

Returns the name of the Composition, unique within type.

Returns:

  • (String) —

    the name of the Composition, unique within type



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
# File 'app/models/composition.rb', line 28

class Composition < ApplicationRecord
  include Housekeeping
  include Shared::IsRender
  include Shared::Pinnable

  # Only true or nil
  normalizes :is_community, with: -> (v) { v.presence }

  before_validation :set_community_project_id

  after_save :set_composition_items_project_id, if: :saved_change_to_project_id?

  has_many :composition_items, inverse_of: :composition, dependent: :destroy

  scope :visible_to_project, -> (project_id) {
    where(project_id:).or(where(is_community: true))
  }

  validates_presence_of :type, :name
  validates :name, uniqueness: { scope: [:project_id, :type] }
  validate :is_community_is_permitted
  validate :community_has_no_item_objects

  # @return [Boolean]
  #   true if *some* instances may be shared across projects (compare
  #   IsData's class-level .is_community?, which means *all* instances are).
  #   Subclasses that reference only model attributes and attribute
  #   modifiers, never instance data, may override this.
  def self.community_permitted?
    false
  end

  # @return [Array of Integer]
  #   ids of the Compositions (of this class) visible to the project that
  #   user_id last changed, most recent first. A change to any item counts
  #   as a change to its Composition. Destroyed items leave no trace.
  def self.used_recently(user_id, project_id)
    visible = visible_to_project(project_id)

    own = visible.where(updated_by_id: user_id)
      .select(:id, :updated_at)
    items = CompositionItem
      .where(updated_by_id: user_id, composition_id: visible.select(:id))
      .select('composition_id AS id', :updated_at)

    Composition
      .from("(#{own.to_sql} UNION ALL #{items.to_sql}) AS used")
      .group('used.id')
      .order(Arel.sql('MAX(used.updated_at) DESC'))
      .limit(10)
      .pluck('used.id')
  end

  # @return [Hash]
  #   pinboard, recent (the Compositions the user worked on last, most
  #   recent first) and quick (inserted pins plus the 4 most recent). Call
  #   on a subclass, e.g. Layout::LightTable, for only its Compositions.
  def self.select_optimized(user_id, project_id)
    q = visible_to_project(project_id)
    pinned = q.pinned_by(user_id).pinned_in_project(project_id)

    r = used_recently(user_id, project_id)
    recent = q.where(id: r).to_a.sort_by { |c| r.index(c.id) }

    {
      quick: (pinned.pinboard_inserted.to_a + recent.first(4)).uniq,
      pinboard: pinned.pinboard_ordered.to_a,
      recent:
    }
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects, which checks the class. Per record,
  #   unlike Data where community is a property of the class. There is no
  #   class-level .is_community? here, nothing asks it of Composition.
  def is_community?
    is_community == true
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects so that community records are not
  #   required to have a project
  def annotates_community_object?
    is_community?
  end

  protected

  def is_community_is_permitted
    if is_community? && !self.class.community_permitted?
      errors.add(:is_community, "is not permitted for #{type}")
    end
  end

  # Community Compositions reference model attributes, not instance data.
  def community_has_no_item_objects
    if is_community? && persisted? &&
        composition_items.where.not(composition_item_object_id: nil).exists?
      errors.add(:is_community, 'is not permitted when items reference objects')
    end
  end

  def set_composition_items_project_id
    composition_items.update_all(project_id:)
  end

  def set_community_project_id
    if is_community?
      self.project_id = nil
    else
      self.project_id ||= Current.project_id
    end
  end

end

#project_id ⇒ Integer?

Returns the project ID, nil when is_community.

Returns:

  • (Integer, nil) —

    the project ID, nil when is_community



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
# File 'app/models/composition.rb', line 28

class Composition < ApplicationRecord
  include Housekeeping
  include Shared::IsRender
  include Shared::Pinnable

  # Only true or nil
  normalizes :is_community, with: -> (v) { v.presence }

  before_validation :set_community_project_id

  after_save :set_composition_items_project_id, if: :saved_change_to_project_id?

  has_many :composition_items, inverse_of: :composition, dependent: :destroy

  scope :visible_to_project, -> (project_id) {
    where(project_id:).or(where(is_community: true))
  }

  validates_presence_of :type, :name
  validates :name, uniqueness: { scope: [:project_id, :type] }
  validate :is_community_is_permitted
  validate :community_has_no_item_objects

  # @return [Boolean]
  #   true if *some* instances may be shared across projects (compare
  #   IsData's class-level .is_community?, which means *all* instances are).
  #   Subclasses that reference only model attributes and attribute
  #   modifiers, never instance data, may override this.
  def self.community_permitted?
    false
  end

  # @return [Array of Integer]
  #   ids of the Compositions (of this class) visible to the project that
  #   user_id last changed, most recent first. A change to any item counts
  #   as a change to its Composition. Destroyed items leave no trace.
  def self.used_recently(user_id, project_id)
    visible = visible_to_project(project_id)

    own = visible.where(updated_by_id: user_id)
      .select(:id, :updated_at)
    items = CompositionItem
      .where(updated_by_id: user_id, composition_id: visible.select(:id))
      .select('composition_id AS id', :updated_at)

    Composition
      .from("(#{own.to_sql} UNION ALL #{items.to_sql}) AS used")
      .group('used.id')
      .order(Arel.sql('MAX(used.updated_at) DESC'))
      .limit(10)
      .pluck('used.id')
  end

  # @return [Hash]
  #   pinboard, recent (the Compositions the user worked on last, most
  #   recent first) and quick (inserted pins plus the 4 most recent). Call
  #   on a subclass, e.g. Layout::LightTable, for only its Compositions.
  def self.select_optimized(user_id, project_id)
    q = visible_to_project(project_id)
    pinned = q.pinned_by(user_id).pinned_in_project(project_id)

    r = used_recently(user_id, project_id)
    recent = q.where(id: r).to_a.sort_by { |c| r.index(c.id) }

    {
      quick: (pinned.pinboard_inserted.to_a + recent.first(4)).uniq,
      pinboard: pinned.pinboard_ordered.to_a,
      recent:
    }
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects, which checks the class. Per record,
  #   unlike Data where community is a property of the class. There is no
  #   class-level .is_community? here, nothing asks it of Composition.
  def is_community?
    is_community == true
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects so that community records are not
  #   required to have a project
  def annotates_community_object?
    is_community?
  end

  protected

  def is_community_is_permitted
    if is_community? && !self.class.community_permitted?
      errors.add(:is_community, "is not permitted for #{type}")
    end
  end

  # Community Compositions reference model attributes, not instance data.
  def community_has_no_item_objects
    if is_community? && persisted? &&
        composition_items.where.not(composition_item_object_id: nil).exists?
      errors.add(:is_community, 'is not permitted when items reference objects')
    end
  end

  def set_composition_items_project_id
    composition_items.update_all(project_id:)
  end

  def set_community_project_id
    if is_community?
      self.project_id = nil
    else
      self.project_id ||= Current.project_id
    end
  end

end

#type ⇒ String

Returns the subclass, e.g. Layout or Template.

Returns:

  • (String) —

    the subclass, e.g. Layout or Template



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
# File 'app/models/composition.rb', line 28

class Composition < ApplicationRecord
  include Housekeeping
  include Shared::IsRender
  include Shared::Pinnable

  # Only true or nil
  normalizes :is_community, with: -> (v) { v.presence }

  before_validation :set_community_project_id

  after_save :set_composition_items_project_id, if: :saved_change_to_project_id?

  has_many :composition_items, inverse_of: :composition, dependent: :destroy

  scope :visible_to_project, -> (project_id) {
    where(project_id:).or(where(is_community: true))
  }

  validates_presence_of :type, :name
  validates :name, uniqueness: { scope: [:project_id, :type] }
  validate :is_community_is_permitted
  validate :community_has_no_item_objects

  # @return [Boolean]
  #   true if *some* instances may be shared across projects (compare
  #   IsData's class-level .is_community?, which means *all* instances are).
  #   Subclasses that reference only model attributes and attribute
  #   modifiers, never instance data, may override this.
  def self.community_permitted?
    false
  end

  # @return [Array of Integer]
  #   ids of the Compositions (of this class) visible to the project that
  #   user_id last changed, most recent first. A change to any item counts
  #   as a change to its Composition. Destroyed items leave no trace.
  def self.used_recently(user_id, project_id)
    visible = visible_to_project(project_id)

    own = visible.where(updated_by_id: user_id)
      .select(:id, :updated_at)
    items = CompositionItem
      .where(updated_by_id: user_id, composition_id: visible.select(:id))
      .select('composition_id AS id', :updated_at)

    Composition
      .from("(#{own.to_sql} UNION ALL #{items.to_sql}) AS used")
      .group('used.id')
      .order(Arel.sql('MAX(used.updated_at) DESC'))
      .limit(10)
      .pluck('used.id')
  end

  # @return [Hash]
  #   pinboard, recent (the Compositions the user worked on last, most
  #   recent first) and quick (inserted pins plus the 4 most recent). Call
  #   on a subclass, e.g. Layout::LightTable, for only its Compositions.
  def self.select_optimized(user_id, project_id)
    q = visible_to_project(project_id)
    pinned = q.pinned_by(user_id).pinned_in_project(project_id)

    r = used_recently(user_id, project_id)
    recent = q.where(id: r).to_a.sort_by { |c| r.index(c.id) }

    {
      quick: (pinned.pinboard_inserted.to_a + recent.first(4)).uniq,
      pinboard: pinned.pinboard_ordered.to_a,
      recent:
    }
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects, which checks the class. Per record,
  #   unlike Data where community is a property of the class. There is no
  #   class-level .is_community? here, nothing asks it of Composition.
  def is_community?
    is_community == true
  end

  # @return [Boolean]
  #   overrides Housekeeping::Projects so that community records are not
  #   required to have a project
  def annotates_community_object?
    is_community?
  end

  protected

  def is_community_is_permitted
    if is_community? && !self.class.community_permitted?
      errors.add(:is_community, "is not permitted for #{type}")
    end
  end

  # Community Compositions reference model attributes, not instance data.
  def community_has_no_item_objects
    if is_community? && persisted? &&
        composition_items.where.not(composition_item_object_id: nil).exists?
      errors.add(:is_community, 'is not permitted when items reference objects')
    end
  end

  def set_composition_items_project_id
    composition_items.update_all(project_id:)
  end

  def set_community_project_id
    if is_community?
      self.project_id = nil
    else
      self.project_id ||= Current.project_id
    end
  end

end

Class Method Details

.community_permitted? ⇒ Boolean

Returns true if some instances may be shared across projects (compare IsData's class-level .is_community?, which means all instances are). Subclasses that reference only model attributes and attribute modifiers, never instance data, may override this.

Returns:

  • (Boolean) —

    true if some instances may be shared across projects (compare IsData's class-level .is_community?, which means all instances are). Subclasses that reference only model attributes and attribute modifiers, never instance data, may override this.



56
57
58
# File 'app/models/composition.rb', line 56

def self.community_permitted?
  false
end

.select_optimized(user_id, project_id) ⇒ Hash

Returns pinboard, recent (the Compositions the user worked on last, most recent first) and quick (inserted pins plus the 4 most recent). Call on a subclass, e.g. Layout::LightTable, for only its Compositions.

Returns:

  • (Hash) —

    pinboard, recent (the Compositions the user worked on last, most recent first) and quick (inserted pins plus the 4 most recent). Call on a subclass, e.g. Layout::LightTable, for only its Compositions.



85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/composition.rb', line 85

def self.select_optimized(user_id, project_id)
  q = visible_to_project(project_id)
  pinned = q.pinned_by(user_id).pinned_in_project(project_id)

  r = used_recently(user_id, project_id)
  recent = q.where(id: r).to_a.sort_by { |c| r.index(c.id) }

  {
    quick: (pinned.pinboard_inserted.to_a + recent.first(4)).uniq,
    pinboard: pinned.pinboard_ordered.to_a,
    recent:
  }
end

.used_recently(user_id, project_id) ⇒ Array of Integer

Returns ids of the Compositions (of this class) visible to the project that user_id last changed, most recent first. A change to any item counts as a change to its Composition. Destroyed items leave no trace.

Returns:

  • (Array of Integer) —

    ids of the Compositions (of this class) visible to the project that user_id last changed, most recent first. A change to any item counts as a change to its Composition. Destroyed items leave no trace.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/models/composition.rb', line 64

def self.used_recently(user_id, project_id)
  visible = visible_to_project(project_id)

  own = visible.where(updated_by_id: user_id)
    .select(:id, :updated_at)
  items = CompositionItem
    .where(updated_by_id: user_id, composition_id: visible.select(:id))
    .select('composition_id AS id', :updated_at)

  Composition
    .from("(#{own.to_sql} UNION ALL #{items.to_sql}) AS used")
    .group('used.id')
    .order(Arel.sql('MAX(used.updated_at) DESC'))
    .limit(10)
    .pluck('used.id')
end

Instance Method Details

#annotates_community_object? ⇒ Boolean

Returns overrides Housekeeping::Projects so that community records are not required to have a project.

Returns:

  • (Boolean) —

    overrides Housekeeping::Projects so that community records are not required to have a project



110
111
112
# File 'app/models/composition.rb', line 110

def annotates_community_object?
  is_community?
end

#community_has_no_item_objects ⇒ Object (protected)

Community Compositions reference model attributes, not instance data.



123
124
125
126
127
128
# File 'app/models/composition.rb', line 123

def community_has_no_item_objects
  if is_community? && persisted? &&
      composition_items.where.not(composition_item_object_id: nil).exists?
    errors.add(:is_community, 'is not permitted when items reference objects')
  end
end

#is_community? ⇒ Boolean

Returns overrides Housekeeping::Projects, which checks the class. Per record, unlike Data where community is a property of the class. There is no class-level .is_community? here, nothing asks it of Composition.

Returns:

  • (Boolean) —

    overrides Housekeeping::Projects, which checks the class. Per record, unlike Data where community is a property of the class. There is no class-level .is_community? here, nothing asks it of Composition.



103
104
105
# File 'app/models/composition.rb', line 103

def is_community?
  is_community == true
end

#is_community_is_permitted ⇒ Object (protected)



116
117
118
119
120
# File 'app/models/composition.rb', line 116

def is_community_is_permitted
  if is_community? && !self.class.community_permitted?
    errors.add(:is_community, "is not permitted for #{type}")
  end
end

#set_community_project_id ⇒ Object (protected)



134
135
136
137
138
139
140
# File 'app/models/composition.rb', line 134

def set_community_project_id
  if is_community?
    self.project_id = nil
  else
    self.project_id ||= Current.project_id
  end
end

#set_composition_items_project_id ⇒ Object (protected)



130
131
132
# File 'app/models/composition.rb', line 130

def set_composition_items_project_id
  composition_items.update_all(project_id:)
end