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
-
#derivatives(*args) ⇒ Object
hacky :(.
-
#derivatives=(*args) ⇒ Object
hacky :(.
-
#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
#initialize(*_) ⇒ Model
Returns a new instance of Model.
76 77 78 79 |
# File 'app/models/kithe/model.rb', line 76 def initialize(*_) raise TypeError.new("Kithe::Model is abstract and cannot be initialized") if self.class == ::Kithe::Model super end |
Instance Method Details
#derivatives(*args) ⇒ Object
hacky :(
104 105 106 107 |
# File 'app/models/kithe/model.rb', line 104 def derivatives(*args) raise TypeError.new("Only valid on Kithe::Asset") unless self.kind_of?(Kithe::Asset) super end |
#derivatives=(*args) ⇒ Object
hacky :(
109 110 111 112 |
# File 'app/models/kithe/model.rb', line 109 def derivatives=(*args) raise TypeError.new("Only valid on Kithe::Asset") unless self.kind_of?(Kithe::Asset) super end |
#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
89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'app/models/kithe/model.rb', line 89 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.
118 119 120 121 |
# File 'app/models/kithe/model.rb', line 118 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!
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 |
# File 'app/models/kithe/model.rb', line 131 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 = " WITH RECURSIVE find_terminal(id, link) AS (\n SELECT m.id, m.representative_id\n FROM kithe_models m\n WHERE m.id = $1\n UNION\n SELECT m.id, m.representative_id\n FROM kithe_models m, find_terminal ft\n WHERE m.id = ft.link\n ) SELECT id\n FROM find_terminal\n WHERE link IS NULL\n LIMIT 1;\n EOS\n\n # trying to use a prepared statement, hoping it means performance advantage\n result = self.class.connection.select_all(\n recursive_cte,\n \"set_leaf_representative\",\n [[nil, self.representative_id]],\n preparable: true\n ).first.try(:dig, \"id\")\n\n self.leaf_representative_id = result\nend\n" |
#to_param ⇒ Object
We want friendlier_id to be in URLs, not id
82 83 84 |
# File 'app/models/kithe/model.rb', line 82 def to_param friendlier_id end |