Class: Content

Overview

Content is text related blocks, at present it only pertains to Otus. It requires both a Topic and an Otu. Future extensions may be added to use the model for Projects, etc. via STI.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Shared::IsData

#errors_excepting, #full_error_messages_excepting, #identical, #is_community?, #is_destroyable?, #is_editable?, #is_in_use?, #is_in_users_projects?, #metamorphosize, #similar

Methods included from Shared::DataAttributes

#import_attributes, #internal_attributes, #keyword_value_hash, #reject_data_attributes

Methods included from Shared::HasPapertrail

#attribute_updated, #attribute_updater

Methods included from Shared::Attributions

#attributed?, #reject_attribution

Methods included from Shared::Citations

#cited?, #mark_citations_for_destruction, #nomenclature_date, #origin_citation_source_id, #reject_citations, #requires_citation?, #sources_by_topic_id

Methods included from Shared::Confidences

#reject_confidences

Methods included from Shared::Depictions

#has_depictions?, #image_array=, #reject_depictions, #reject_images

Methods included from Housekeeping

#has_polymorphic_relationship?

Methods inherited from ApplicationRecord

transaction_with_retry

Instance Attribute Details

#is_publicObject

Returns the value of attribute is_public.



37
38
39
# File 'app/models/content.rb', line 37

def is_public
  @is_public
end

#otu_idInteger

When OtuContent::Text the id of the Otu the content pertains to. At present required.

Returns:

  • (Integer)


25
26
27
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
# File 'app/models/content.rb', line 25

class Content < ApplicationRecord
  include Housekeeping
  include Shared::Depictions
  include Shared::Confidences
  include Shared::Citations
  include Shared::Attributions
  include Shared::HasPapertrail
  include Shared::DataAttributes # TODO: reconsider, why is this here?  Should be removed, use case is currently cross reference to an identifier, if required use Identifier
  include Shared::IsData

  ignore_whitespace_on(:text)

  attr_accessor :is_public

  after_save :publish, if: -> { (is_public == true) || is_public == '1' }
  after_save :unpublish, if: -> { (is_public == false) || (is_public == '0') }

  belongs_to :otu, inverse_of: :contents
  belongs_to :topic, inverse_of: :contents
  has_one :public_content, inverse_of: :content, dependent: :destroy
  belongs_to :language

  validate :topic_id_is_type_topic

  validates_uniqueness_of :topic_id, scope: [:otu_id]
  validates_presence_of :text, :topic_id, :otu_id

  # scope :for_otu_page_layout, -> (otu_page_layout_id) {
  #   where('otu_page_layout_id = ?', otu_page_layout.od)
  # }

  # @return [Boolean]
  #    true if this content has been published
  def is_published?
    public_content.present?
  end

  # TODO: this will have to be updated in subclasses.
  def publish
    public_content.delete if public_content
    PublicContent.create!(
      content: self,
      topic:,
      text:,
      otu:
    )
  end

  def unpublish
    public_content&.destroy
  end

  # OTU_PAGE_LAYOUTS
  #       V
  # OTU_PAGE_LAYOUT_SECTIONS ^ .otu_page_layout_id v .topic_id
  #       V
  #     TOPICS
  #       V
  #    CONTENTS              v otu_id              ^ .topic_id
  #       ^
  #      OTU
  #
  # Given an otu_page_layout id. find all the topics
  # For this otu_page_layout, find the topics (ControlledVocabularyTerm.of_type(:topic))

  def self.for_page_layout(otu_page_layout_id)
    where('topic_id in (?)', OtuPageLayout.where(id: otu_page_layout_id).first.topics.pluck(:id))
  end

  def self.find_for_autocomplete(params)
    where('text ILIKE ?', "%#{params[:term]}%")
  end

  def self.used_recently(user_id, project_id)
    Content.touched_by(user_id).where(project_id:).order(updated_at: :desc).limit(6).to_a
  end

  def self.select_optimized(user_id, project_id)
    r = used_recently(user_id, project_id)

    h = {
      quick: Content.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a,
      pinboard: Content.pinned_by(user_id).where(project_id:).to_a,
      recent: used_recently(user_id, project_id)
    }

    h
  end

  private

  def topic_id_is_type_topic
    if topic_id
      errors.add(:topic_id, 'is not a Topic id') if !Topic.find(topic_id)
    end
  end
end

#project_idInteger

the project ID

Returns:

  • (Integer)


25
26
27
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
# File 'app/models/content.rb', line 25

class Content < ApplicationRecord
  include Housekeeping
  include Shared::Depictions
  include Shared::Confidences
  include Shared::Citations
  include Shared::Attributions
  include Shared::HasPapertrail
  include Shared::DataAttributes # TODO: reconsider, why is this here?  Should be removed, use case is currently cross reference to an identifier, if required use Identifier
  include Shared::IsData

  ignore_whitespace_on(:text)

  attr_accessor :is_public

  after_save :publish, if: -> { (is_public == true) || is_public == '1' }
  after_save :unpublish, if: -> { (is_public == false) || (is_public == '0') }

  belongs_to :otu, inverse_of: :contents
  belongs_to :topic, inverse_of: :contents
  has_one :public_content, inverse_of: :content, dependent: :destroy
  belongs_to :language

  validate :topic_id_is_type_topic

  validates_uniqueness_of :topic_id, scope: [:otu_id]
  validates_presence_of :text, :topic_id, :otu_id

  # scope :for_otu_page_layout, -> (otu_page_layout_id) {
  #   where('otu_page_layout_id = ?', otu_page_layout.od)
  # }

  # @return [Boolean]
  #    true if this content has been published
  def is_published?
    public_content.present?
  end

  # TODO: this will have to be updated in subclasses.
  def publish
    public_content.delete if public_content
    PublicContent.create!(
      content: self,
      topic:,
      text:,
      otu:
    )
  end

  def unpublish
    public_content&.destroy
  end

  # OTU_PAGE_LAYOUTS
  #       V
  # OTU_PAGE_LAYOUT_SECTIONS ^ .otu_page_layout_id v .topic_id
  #       V
  #     TOPICS
  #       V
  #    CONTENTS              v otu_id              ^ .topic_id
  #       ^
  #      OTU
  #
  # Given an otu_page_layout id. find all the topics
  # For this otu_page_layout, find the topics (ControlledVocabularyTerm.of_type(:topic))

  def self.for_page_layout(otu_page_layout_id)
    where('topic_id in (?)', OtuPageLayout.where(id: otu_page_layout_id).first.topics.pluck(:id))
  end

  def self.find_for_autocomplete(params)
    where('text ILIKE ?', "%#{params[:term]}%")
  end

  def self.used_recently(user_id, project_id)
    Content.touched_by(user_id).where(project_id:).order(updated_at: :desc).limit(6).to_a
  end

  def self.select_optimized(user_id, project_id)
    r = used_recently(user_id, project_id)

    h = {
      quick: Content.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a,
      pinboard: Content.pinned_by(user_id).where(project_id:).to_a,
      recent: used_recently(user_id, project_id)
    }

    h
  end

  private

  def topic_id_is_type_topic
    if topic_id
      errors.add(:topic_id, 'is not a Topic id') if !Topic.find(topic_id)
    end
  end
end

#revision_idInteger

Stubbed placeholder for Revision (sensus taxonomy) model. NOT PRESENTLY USED.

Returns:

  • (Integer)


25
26
27
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
# File 'app/models/content.rb', line 25

class Content < ApplicationRecord
  include Housekeeping
  include Shared::Depictions
  include Shared::Confidences
  include Shared::Citations
  include Shared::Attributions
  include Shared::HasPapertrail
  include Shared::DataAttributes # TODO: reconsider, why is this here?  Should be removed, use case is currently cross reference to an identifier, if required use Identifier
  include Shared::IsData

  ignore_whitespace_on(:text)

  attr_accessor :is_public

  after_save :publish, if: -> { (is_public == true) || is_public == '1' }
  after_save :unpublish, if: -> { (is_public == false) || (is_public == '0') }

  belongs_to :otu, inverse_of: :contents
  belongs_to :topic, inverse_of: :contents
  has_one :public_content, inverse_of: :content, dependent: :destroy
  belongs_to :language

  validate :topic_id_is_type_topic

  validates_uniqueness_of :topic_id, scope: [:otu_id]
  validates_presence_of :text, :topic_id, :otu_id

  # scope :for_otu_page_layout, -> (otu_page_layout_id) {
  #   where('otu_page_layout_id = ?', otu_page_layout.od)
  # }

  # @return [Boolean]
  #    true if this content has been published
  def is_published?
    public_content.present?
  end

  # TODO: this will have to be updated in subclasses.
  def publish
    public_content.delete if public_content
    PublicContent.create!(
      content: self,
      topic:,
      text:,
      otu:
    )
  end

  def unpublish
    public_content&.destroy
  end

  # OTU_PAGE_LAYOUTS
  #       V
  # OTU_PAGE_LAYOUT_SECTIONS ^ .otu_page_layout_id v .topic_id
  #       V
  #     TOPICS
  #       V
  #    CONTENTS              v otu_id              ^ .topic_id
  #       ^
  #      OTU
  #
  # Given an otu_page_layout id. find all the topics
  # For this otu_page_layout, find the topics (ControlledVocabularyTerm.of_type(:topic))

  def self.for_page_layout(otu_page_layout_id)
    where('topic_id in (?)', OtuPageLayout.where(id: otu_page_layout_id).first.topics.pluck(:id))
  end

  def self.find_for_autocomplete(params)
    where('text ILIKE ?', "%#{params[:term]}%")
  end

  def self.used_recently(user_id, project_id)
    Content.touched_by(user_id).where(project_id:).order(updated_at: :desc).limit(6).to_a
  end

  def self.select_optimized(user_id, project_id)
    r = used_recently(user_id, project_id)

    h = {
      quick: Content.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a,
      pinboard: Content.pinned_by(user_id).where(project_id:).to_a,
      recent: used_recently(user_id, project_id)
    }

    h
  end

  private

  def topic_id_is_type_topic
    if topic_id
      errors.add(:topic_id, 'is not a Topic id') if !Topic.find(topic_id)
    end
  end
end

#textString

The written content.

Returns:

  • (String)


25
26
27
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
# File 'app/models/content.rb', line 25

class Content < ApplicationRecord
  include Housekeeping
  include Shared::Depictions
  include Shared::Confidences
  include Shared::Citations
  include Shared::Attributions
  include Shared::HasPapertrail
  include Shared::DataAttributes # TODO: reconsider, why is this here?  Should be removed, use case is currently cross reference to an identifier, if required use Identifier
  include Shared::IsData

  ignore_whitespace_on(:text)

  attr_accessor :is_public

  after_save :publish, if: -> { (is_public == true) || is_public == '1' }
  after_save :unpublish, if: -> { (is_public == false) || (is_public == '0') }

  belongs_to :otu, inverse_of: :contents
  belongs_to :topic, inverse_of: :contents
  has_one :public_content, inverse_of: :content, dependent: :destroy
  belongs_to :language

  validate :topic_id_is_type_topic

  validates_uniqueness_of :topic_id, scope: [:otu_id]
  validates_presence_of :text, :topic_id, :otu_id

  # scope :for_otu_page_layout, -> (otu_page_layout_id) {
  #   where('otu_page_layout_id = ?', otu_page_layout.od)
  # }

  # @return [Boolean]
  #    true if this content has been published
  def is_published?
    public_content.present?
  end

  # TODO: this will have to be updated in subclasses.
  def publish
    public_content.delete if public_content
    PublicContent.create!(
      content: self,
      topic:,
      text:,
      otu:
    )
  end

  def unpublish
    public_content&.destroy
  end

  # OTU_PAGE_LAYOUTS
  #       V
  # OTU_PAGE_LAYOUT_SECTIONS ^ .otu_page_layout_id v .topic_id
  #       V
  #     TOPICS
  #       V
  #    CONTENTS              v otu_id              ^ .topic_id
  #       ^
  #      OTU
  #
  # Given an otu_page_layout id. find all the topics
  # For this otu_page_layout, find the topics (ControlledVocabularyTerm.of_type(:topic))

  def self.for_page_layout(otu_page_layout_id)
    where('topic_id in (?)', OtuPageLayout.where(id: otu_page_layout_id).first.topics.pluck(:id))
  end

  def self.find_for_autocomplete(params)
    where('text ILIKE ?', "%#{params[:term]}%")
  end

  def self.used_recently(user_id, project_id)
    Content.touched_by(user_id).where(project_id:).order(updated_at: :desc).limit(6).to_a
  end

  def self.select_optimized(user_id, project_id)
    r = used_recently(user_id, project_id)

    h = {
      quick: Content.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a,
      pinboard: Content.pinned_by(user_id).where(project_id:).to_a,
      recent: used_recently(user_id, project_id)
    }

    h
  end

  private

  def topic_id_is_type_topic
    if topic_id
      errors.add(:topic_id, 'is not a Topic id') if !Topic.find(topic_id)
    end
  end
end

#topic_idInteger

When OtuContent::Text the id of the Topic the content pertains to. At present required.

Returns:

  • (Integer)


25
26
27
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
# File 'app/models/content.rb', line 25

class Content < ApplicationRecord
  include Housekeeping
  include Shared::Depictions
  include Shared::Confidences
  include Shared::Citations
  include Shared::Attributions
  include Shared::HasPapertrail
  include Shared::DataAttributes # TODO: reconsider, why is this here?  Should be removed, use case is currently cross reference to an identifier, if required use Identifier
  include Shared::IsData

  ignore_whitespace_on(:text)

  attr_accessor :is_public

  after_save :publish, if: -> { (is_public == true) || is_public == '1' }
  after_save :unpublish, if: -> { (is_public == false) || (is_public == '0') }

  belongs_to :otu, inverse_of: :contents
  belongs_to :topic, inverse_of: :contents
  has_one :public_content, inverse_of: :content, dependent: :destroy
  belongs_to :language

  validate :topic_id_is_type_topic

  validates_uniqueness_of :topic_id, scope: [:otu_id]
  validates_presence_of :text, :topic_id, :otu_id

  # scope :for_otu_page_layout, -> (otu_page_layout_id) {
  #   where('otu_page_layout_id = ?', otu_page_layout.od)
  # }

  # @return [Boolean]
  #    true if this content has been published
  def is_published?
    public_content.present?
  end

  # TODO: this will have to be updated in subclasses.
  def publish
    public_content.delete if public_content
    PublicContent.create!(
      content: self,
      topic:,
      text:,
      otu:
    )
  end

  def unpublish
    public_content&.destroy
  end

  # OTU_PAGE_LAYOUTS
  #       V
  # OTU_PAGE_LAYOUT_SECTIONS ^ .otu_page_layout_id v .topic_id
  #       V
  #     TOPICS
  #       V
  #    CONTENTS              v otu_id              ^ .topic_id
  #       ^
  #      OTU
  #
  # Given an otu_page_layout id. find all the topics
  # For this otu_page_layout, find the topics (ControlledVocabularyTerm.of_type(:topic))

  def self.for_page_layout(otu_page_layout_id)
    where('topic_id in (?)', OtuPageLayout.where(id: otu_page_layout_id).first.topics.pluck(:id))
  end

  def self.find_for_autocomplete(params)
    where('text ILIKE ?', "%#{params[:term]}%")
  end

  def self.used_recently(user_id, project_id)
    Content.touched_by(user_id).where(project_id:).order(updated_at: :desc).limit(6).to_a
  end

  def self.select_optimized(user_id, project_id)
    r = used_recently(user_id, project_id)

    h = {
      quick: Content.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a,
      pinboard: Content.pinned_by(user_id).where(project_id:).to_a,
      recent: used_recently(user_id, project_id)
    }

    h
  end

  private

  def topic_id_is_type_topic
    if topic_id
      errors.add(:topic_id, 'is not a Topic id') if !Topic.find(topic_id)
    end
  end
end

Class Method Details

.find_for_autocomplete(params) ⇒ Object



94
95
96
# File 'app/models/content.rb', line 94

def self.find_for_autocomplete(params)
  where('text ILIKE ?', "%#{params[:term]}%")
end

.for_page_layout(otu_page_layout_id) ⇒ Object

OTU_PAGE_LAYOUTS

V

OTU_PAGE_LAYOUT_SECTIONS ^ .otu_page_layout_id v .topic_id

   V
 TOPICS
   V
CONTENTS              v otu_id              ^ .topic_id
   ^
  OTU

Given an otu_page_layout id. find all the topics For this otu_page_layout, find the topics (ControlledVocabularyTerm.of_type(:topic))



90
91
92
# File 'app/models/content.rb', line 90

def self.for_page_layout(otu_page_layout_id)
  where('topic_id in (?)', OtuPageLayout.where(id: otu_page_layout_id).first.topics.pluck(:id))
end

.select_optimized(user_id, project_id) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
# File 'app/models/content.rb', line 102

def self.select_optimized(user_id, project_id)
  r = used_recently(user_id, project_id)

  h = {
    quick: Content.pinned_by(user_id).pinboard_inserted.where(project_id:).to_a,
    pinboard: Content.pinned_by(user_id).where(project_id:).to_a,
    recent: used_recently(user_id, project_id)
  }

  h
end

.used_recently(user_id, project_id) ⇒ Object



98
99
100
# File 'app/models/content.rb', line 98

def self.used_recently(user_id, project_id)
  Content.touched_by(user_id).where(project_id:).order(updated_at: :desc).limit(6).to_a
end

Instance Method Details

#is_published?Boolean

Returns true if this content has been published.

Returns:

  • (Boolean)

    true if this content has been published



58
59
60
# File 'app/models/content.rb', line 58

def is_published?
  public_content.present?
end

#publishObject

TODO: this will have to be updated in subclasses.



63
64
65
66
67
68
69
70
71
# File 'app/models/content.rb', line 63

def publish
  public_content.delete if public_content
  PublicContent.create!(
    content: self,
    topic:,
    text:,
    otu:
  )
end

#topic_id_is_type_topicObject (private)



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

def topic_id_is_type_topic
  if topic_id
    errors.add(:topic_id, 'is not a Topic id') if !Topic.find(topic_id)
  end
end

#unpublishObject



73
74
75
# File 'app/models/content.rb', line 73

def unpublish
  public_content&.destroy
end