Class: Kithe::Model
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Kithe::Model
- Includes:
- AttrJson::NestedAttributes, AttrJson::Record, AttrJson::Record::Dirty, Indexable, StiPreload
- Defined in:
- app/models/kithe/model.rb
Direct Known Subclasses
Instance Method Summary collapse
-
#friendlier_id(*_) ⇒ Object
Due to rails bug, we don’t immediately have the database-provided value after create.
-
#initialize(*_) ⇒ Model
constructor
A new instance of Model.
-
#leaf_representative ⇒ Object
insist that leaf_representative is an Asset, otherwise return nil.
-
#set_leaf_representative ⇒ Object
if a representative is set, set leaf_representative by following the tree with an efficient recursive CTE to find proper value.
-
#to_param ⇒ Object
We want friendlier_id to be in URLs, not id.
Methods included from Indexable
auto_callbacks?, index_with, #update_index
Constructor Details
Instance Method Details
#friendlier_id(*_) ⇒ Object
Due to rails bug, we don’t immediately have the database-provided value after create. :( If we ask for it and it’s empty, go to the db to get it github.com/rails/rails/issues/21627
80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'app/models/kithe/model.rb', line 80 def friendlier_id(*_) in_memory = super if !in_memory && persisted? && !@friendlier_id_retrieved in_memory = self.class.where(id: id).limit(1).pluck(:friendlier_id).first write_attribute(:friendlier_id, in_memory) clear_attribute_change(:friendlier_id) # just to avoid doing it multiple times if it's still unset in db for some reason @friendlier_id_retrieved = true end in_memory end |
#leaf_representative ⇒ Object
insist that leaf_representative is an Asset, otherwise return nil. nil means there is no asset leaf, and lets caller rely on leaf being an asset.
97 98 99 100 |
# File 'app/models/kithe/model.rb', line 97 def leaf_representative leaf = super leaf.kind_of?(Kithe::Asset) ? leaf : nil end |
#set_leaf_representative ⇒ Object
if a representative is set, set leaf_representative by following the tree with an efficient recursive CTE to find proper value.
Normally this is called for you in callbacks, and you don’t need to call manually. But if things get out of sync, you can.
work.set_leaf_representative
work.save!
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/kithe/model.rb', line 110 def set_leaf_representative if self.kind_of?(Kithe::Asset) # not applicable self.leaf_representative_id = nil end # a postgres recursive CTE to find the ultimate leaf through # a possible chain of works, guarding against cycles. # https://www.postgresql.org/docs/9.1/queries-with.html recursive_cte = <<~EOS WITH RECURSIVE find_terminal(id, link) AS ( SELECT m.id, m.representative_id FROM kithe_models m WHERE m.id = $1 UNION SELECT m.id, m.representative_id FROM kithe_models m, find_terminal ft WHERE m.id = ft.link ) SELECT id FROM find_terminal WHERE link IS NULL LIMIT 1; EOS # trying to use a prepared statement, hoping it means performance advantage result = self.class.connection.select_all( recursive_cte, "set_leaf_representative", [[nil, self.representative_id]], preparable: true ).first.try(:dig, "id") self.leaf_representative_id = result end |
#to_param ⇒ Object
We want friendlier_id to be in URLs, not id
73 74 75 |
# File 'app/models/kithe/model.rb', line 73 def to_param friendlier_id end |