Class: PreparationType

Inherits:
ApplicationRecord show all
Includes:
Housekeeping::Timestamps, Housekeeping::Users, Shared::HasPapertrail, Shared::IsData, Shared::SharedAcrossProjects, Shared::Tags
Defined in:
app/models/preparation_type.rb

Overview

A PreparationType describes how a collection object was prepared for preservation in a collection. At present we're building a shared controlled vocabulary that we may ultimately try and turn into an ontology.

Constant Summary collapse

USED_ON_KLASSES =

The classes that assert a preparation_type_id, and against which recent use is measured for the smart selector.

%w{CollectionObject AnatomicalPart}.freeze

Instance Attribute Summary collapse

Attributes included from Housekeeping::Users

#by

Class Method Summary collapse

Methods included from Shared::IsData

#errors_excepting, #full_error_messages_excepting, #identical, #is_community?, #is_in_use?, #similar

Methods included from Shared::HasPapertrail

#attribute_updated, #attribute_updater, #detect_version

Methods included from Shared::Tags

#reject_tags, #tag_with, #tagged?, #tagged_with?

Methods included from Housekeeping::Users

#set_created_by_id, #set_updated_by_id

Methods inherited from ApplicationRecord

transaction_with_retry

Instance Attribute Details

#definitionString

Returns a definition describing the preparation.

Returns:

  • (String)

    a definition describing the preparation



12
13
14
15
16
17
18
19
20
21
22
23
24
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
# File 'app/models/preparation_type.rb', line 12

class PreparationType < ApplicationRecord
  include Housekeeping::Users
  include Housekeeping::Timestamps
  include Shared::Tags
  include Shared::SharedAcrossProjects
  include Shared::HasPapertrail
  include Shared::IsData

  has_many :collection_objects, dependent: :restrict_with_error, inverse_of: :preparation_type
  has_many :anatomical_parts, inverse_of: :preparation_type, dependent: :restrict_with_error

  validates_presence_of :name, :definition

  validates_uniqueness_of :name
  validates_uniqueness_of :definition

  # The classes that assert a preparation_type_id, and against which recent
  # use is measured for the smart selector.
  USED_ON_KLASSES = %w{CollectionObject AnatomicalPart}.freeze

  # @param used_on [String] one of USED_ON_KLASSES
  # @return [Array]
  #   the ids of the preparation types most recently used by the user in the project
  def self.used_recently(user_id, project_id, used_on)
    return [] unless USED_ON_KLASSES.include?(used_on)

    t = used_on.constantize.arel_table
    p = PreparationType.arel_table

    # i is a select manager
    i = t.project(t['preparation_type_id'], t['updated_at']).from(t)
      .where(t['updated_at'].gt(4.weeks.ago))
      .where(t['updated_by_id'].eq(user_id))
      .where(t['project_id'].eq(project_id))
      .order(t['updated_at'].desc)

    # z is a table alias
    z = i.as('recent_t')

    PreparationType.joins(
      Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['preparation_type_id'].eq(p['id'])))
    ).pluck(:id).uniq
  end

  # @return [Hash]
  #   preparation types optimized for user selection
  def self.select_optimized(user_id, project_id, target)
    r = used_recently(user_id, project_id, target)

    h = {
      quick: [],
      pinboard: PreparationType.pinned_by(user_id).pinned_in_project(project_id).pinboard_ordered.to_a,
      recent: []
    }

    if r.empty?
      h[:quick] = PreparationType.pinned_by(user_id).pinboard_inserted.pinned_in_project(project_id).to_a
    else
      h[:recent] = PreparationType.where(id: r.first(10)).order(:name).to_a
      h[:quick] = (
        PreparationType.pinned_by(user_id).pinboard_inserted.pinned_in_project(project_id).to_a +
        PreparationType.where(id: r.first(4)).order(:name).to_a
      ).uniq
    end

    h
  end

end

#nameString

Returns the name of the preparation.

Returns:

  • (String)

    the name of the preparation



12
13
14
15
16
17
18
19
20
21
22
23
24
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
# File 'app/models/preparation_type.rb', line 12

class PreparationType < ApplicationRecord
  include Housekeeping::Users
  include Housekeeping::Timestamps
  include Shared::Tags
  include Shared::SharedAcrossProjects
  include Shared::HasPapertrail
  include Shared::IsData

  has_many :collection_objects, dependent: :restrict_with_error, inverse_of: :preparation_type
  has_many :anatomical_parts, inverse_of: :preparation_type, dependent: :restrict_with_error

  validates_presence_of :name, :definition

  validates_uniqueness_of :name
  validates_uniqueness_of :definition

  # The classes that assert a preparation_type_id, and against which recent
  # use is measured for the smart selector.
  USED_ON_KLASSES = %w{CollectionObject AnatomicalPart}.freeze

  # @param used_on [String] one of USED_ON_KLASSES
  # @return [Array]
  #   the ids of the preparation types most recently used by the user in the project
  def self.used_recently(user_id, project_id, used_on)
    return [] unless USED_ON_KLASSES.include?(used_on)

    t = used_on.constantize.arel_table
    p = PreparationType.arel_table

    # i is a select manager
    i = t.project(t['preparation_type_id'], t['updated_at']).from(t)
      .where(t['updated_at'].gt(4.weeks.ago))
      .where(t['updated_by_id'].eq(user_id))
      .where(t['project_id'].eq(project_id))
      .order(t['updated_at'].desc)

    # z is a table alias
    z = i.as('recent_t')

    PreparationType.joins(
      Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['preparation_type_id'].eq(p['id'])))
    ).pluck(:id).uniq
  end

  # @return [Hash]
  #   preparation types optimized for user selection
  def self.select_optimized(user_id, project_id, target)
    r = used_recently(user_id, project_id, target)

    h = {
      quick: [],
      pinboard: PreparationType.pinned_by(user_id).pinned_in_project(project_id).pinboard_ordered.to_a,
      recent: []
    }

    if r.empty?
      h[:quick] = PreparationType.pinned_by(user_id).pinboard_inserted.pinned_in_project(project_id).to_a
    else
      h[:recent] = PreparationType.where(id: r.first(10)).order(:name).to_a
      h[:quick] = (
        PreparationType.pinned_by(user_id).pinboard_inserted.pinned_in_project(project_id).to_a +
        PreparationType.where(id: r.first(4)).order(:name).to_a
      ).uniq
    end

    h
  end

end

Class Method Details

.select_optimized(user_id, project_id, target) ⇒ Hash

Returns preparation types optimized for user selection.

Returns:

  • (Hash)

    preparation types optimized for user selection



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'app/models/preparation_type.rb', line 58

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

  h = {
    quick: [],
    pinboard: PreparationType.pinned_by(user_id).pinned_in_project(project_id).pinboard_ordered.to_a,
    recent: []
  }

  if r.empty?
    h[:quick] = PreparationType.pinned_by(user_id).pinboard_inserted.pinned_in_project(project_id).to_a
  else
    h[:recent] = PreparationType.where(id: r.first(10)).order(:name).to_a
    h[:quick] = (
      PreparationType.pinned_by(user_id).pinboard_inserted.pinned_in_project(project_id).to_a +
      PreparationType.where(id: r.first(4)).order(:name).to_a
    ).uniq
  end

  h
end

.used_recently(user_id, project_id, used_on) ⇒ Array

Returns the ids of the preparation types most recently used by the user in the project.

Parameters:

  • used_on (String)

    one of USED_ON_KLASSES

Returns:

  • (Array)

    the ids of the preparation types most recently used by the user in the project



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'app/models/preparation_type.rb', line 35

def self.used_recently(user_id, project_id, used_on)
  return [] unless USED_ON_KLASSES.include?(used_on)

  t = used_on.constantize.arel_table
  p = PreparationType.arel_table

  # i is a select manager
  i = t.project(t['preparation_type_id'], t['updated_at']).from(t)
    .where(t['updated_at'].gt(4.weeks.ago))
    .where(t['updated_by_id'].eq(user_id))
    .where(t['project_id'].eq(project_id))
    .order(t['updated_at'].desc)

  # z is a table alias
  z = i.as('recent_t')

  PreparationType.joins(
    Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['preparation_type_id'].eq(p['id'])))
  ).pluck(:id).uniq
end