Class: Kithe::Model
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Kithe::Model
- Includes:
- AttrJson::NestedAttributes, AttrJson::Record, AttrJson::Record::Dirty, Indexable
- 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.
70 71 72 73 |
# File 'app/models/kithe/model.rb', line 70 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 :(
98 99 100 101 |
# File 'app/models/kithe/model.rb', line 98 def derivatives(*args) raise TypeError.new("Only valid on Kithe::Asset") unless self.kind_of?(Kithe::Asset) super end |
#derivatives=(*args) ⇒ Object
hacky :(
103 104 105 106 |
# File 'app/models/kithe/model.rb', line 103 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
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'app/models/kithe/model.rb', line 83 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.
112 113 114 115 |
# File 'app/models/kithe/model.rb', line 112 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!
125 126 127 128 129 130 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 |
# File 'app/models/kithe/model.rb', line 125 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
76 77 78 |
# File 'app/models/kithe/model.rb', line 76 def to_param friendlier_id end |