Class: Volt::ModelController
- Includes:
- CollectionHelpers, LifecycleCallbacks, ReactiveAccessors
- Defined in:
- lib/volt/controllers/model_controller.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#attrs ⇒ Object
Returns the value of attribute attrs.
-
#section ⇒ Object
The section is assigned a reference to a “DomSection” which has the dom for the controllers view.
Class Method Summary collapse
Instance Method Summary collapse
-
#container ⇒ Object
Container returns the node that is parent to all nodes in the section.
- #controller ⇒ Object
- #dom_nodes ⇒ Object
-
#first_element ⇒ Object
Walks the dom_nodes range until it finds an element.
- #go(url) ⇒ Object
-
#initialize(volt_app, *args) ⇒ ModelController
constructor
A new instance of ModelController.
-
#loaded? ⇒ Boolean
loaded? is a quick way to see if the model for the controller is loaded yet.
- #method_missing(method_name, *args, &block) ⇒ Object
- #model ⇒ Object
-
#model=(val) ⇒ Object
Sets the current model on this controller.
-
#raw(str) ⇒ Object
Raw marks a string as html safe, so bindings can be rendered as html.
-
#redirect_to(url) ⇒ Object
Change the url.
- #require_login(message = 'You must login to access this area.') ⇒ Object
-
#respond_to?(method_name) ⇒ Boolean
Check if this controller responds_to method, or the model.
-
#u ⇒ Object
the u method provides an easy helper to render an unbonud binding.
-
#yield_html ⇒ Object
yield_html renders the content passed into a tag as a string.
Methods included from CollectionHelpers
#channel, #cookies, #flash, #local_store, #page, #params, #store, #tasks, #url, #url_for, #url_with
Methods included from LifecycleCallbacks
included, #run_callbacks, #stop_chain
Methods included from ReactiveAccessors
#__reactive_dependency_get, included
Constructor Details
#initialize(volt_app, *args) ⇒ ModelController
Returns a new instance of ModelController.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/volt/controllers/model_controller.rb', line 145 def initialize(volt_app, *args) @volt_app = volt_app # Track that the initialize was called @__init_called = true default_model = self.class.default_model self.model = default_model if default_model if args[0] # Assign the first passed in argument to attrs self.attrs = args[0] # If a model attribute is passed in, we assign it directly self.model = attrs.locals[:model] if attrs.respond_to?(:model) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
224 225 226 227 228 229 230 231 232 |
# File 'lib/volt/controllers/model_controller.rb', line 224 def method_missing(method_name, *args, &block) model = self.model if model model.send(method_name, *args, &block) else super end end |
Instance Attribute Details
#attrs ⇒ Object
Returns the value of attribute attrs.
143 144 145 |
# File 'lib/volt/controllers/model_controller.rb', line 143 def attrs @attrs end |
#section ⇒ Object
The section is assigned a reference to a “DomSection” which has the dom for the controllers view.
23 24 25 |
# File 'lib/volt/controllers/model_controller.rb', line 23 def section @section end |
Class Method Details
.model(val) ⇒ Object
79 80 81 |
# File 'lib/volt/controllers/model_controller.rb', line 79 def self.model(val) self.default_model = val end |
.new(volt_app, *args, &block) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/volt/controllers/model_controller.rb', line 126 def self.new(volt_app, *args, &block) inst = allocate # In MRI initialize is private for some reason, so call it with send inst.send(:initialize, volt_app, *args, &block) if inst.instance_variable_get('@__init_called') inst.instance_variable_set('@__init_called', nil) else # Initialize was not called, we should warn since this is probably not # the intended behavior. Volt.logger.warn("super should be called when creating a custom initialize on class #{inst.class.to_s}") end inst end |
Instance Method Details
#container ⇒ Object
Container returns the node that is parent to all nodes in the section.
29 30 31 |
# File 'lib/volt/controllers/model_controller.rb', line 29 def container section.container_node end |
#controller ⇒ Object
179 180 181 |
# File 'lib/volt/controllers/model_controller.rb', line 179 def controller @controller ||= Model.new end |
#dom_nodes ⇒ Object
33 34 35 |
# File 'lib/volt/controllers/model_controller.rb', line 33 def dom_nodes section.range end |
#first_element ⇒ Object
Walks the dom_nodes range until it finds an element. Typically this will be the container element without the whitespace text nodes.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/volt/controllers/model_controller.rb', line 39 def first_element range = dom_nodes nodes = `range.startContainer.childNodes` start_index = `range.startOffset` end_index = `range.endOffset` start_index.upto(end_index) do |index| node = `nodes[index]` # Return if an element if `node.nodeType === 1` return node end end return nil end |
#go(url) ⇒ Object
164 165 166 167 168 |
# File 'lib/volt/controllers/model_controller.rb', line 164 def go(url) Volt.logger.warn('Deprecation warning: `go` has been renamed to `redirect_to` for consistency with other frameworks.') redirect_to(url) end |
#loaded? ⇒ Boolean
loaded? is a quick way to see if the model for the controller is loaded yet. If the model is there, it asks the model if its loaded. If the model was set to a promise, it waits for the promise to resolve.
186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/volt/controllers/model_controller.rb', line 186 def loaded? if model.respond_to?(:loaded?) # There is a model and it is loaded return model.loaded? elsif last_promise || model.is_a?(Promise) # The model is a promise or is resolving return false else # Otherwise, its loaded return true end end |
#model ⇒ Object
117 118 119 120 121 122 123 124 |
# File 'lib/volt/controllers/model_controller.rb', line 117 def model model = self.current_model # If the model is a proc, call it now model = model.call if model && model.is_a?(Proc) model end |
#model=(val) ⇒ Object
Sets the current model on this controller
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 |
# File 'lib/volt/controllers/model_controller.rb', line 84 def model=(val) if val.is_a?(Promise) # Resolve the promise before setting self.last_promise = val val.then do |result| # Only assign if nothing else has been assigned since we started the resolve self.model = result if last_promise == val end.fail do |err| Volt.logger.error("Unable to resolve promise assigned to model on #{inspect}") end return end # Clear self.last_promise = nil # Start with a nil reactive value. self.current_model ||= Model.new if Symbol === val || String === val collections = [:page, :store, :params, :controller] if collections.include?(val.to_sym) self.current_model = send(val) else fail "#{val} is not the name of a valid model, choose from: #{collections.join(', ')}" end else self.current_model = val end end |
#raw(str) ⇒ Object
Raw marks a string as html safe, so bindings can be rendered as html. With great power comes great responsibility.
210 211 212 213 |
# File 'lib/volt/controllers/model_controller.rb', line 210 def raw(str) str = str.to_s unless str.is_a?(String) str.html_safe end |
#redirect_to(url) ⇒ Object
Change the url
171 172 173 174 175 176 177 |
# File 'lib/volt/controllers/model_controller.rb', line 171 def redirect_to(url) # We might be in the rendering loop, so wait until the next tick before # we change the url Timers.next_tick do self.url.parse(url) end end |
#require_login(message = 'You must login to access this area.') ⇒ Object
199 200 201 202 203 204 205 206 |
# File 'lib/volt/controllers/model_controller.rb', line 199 def require_login( = 'You must login to access this area.') unless Volt.current_user_id flash._notices << redirect_to '/login' stop_chain end end |
#respond_to?(method_name) ⇒ Boolean
Check if this controller responds_to method, or the model
216 217 218 219 220 221 222 |
# File 'lib/volt/controllers/model_controller.rb', line 216 def respond_to?(method_name) super || begin model = self.model model.respond_to?(method_name) if model end end |
#u ⇒ Object
the u method provides an easy helper to render an unbonud binding. This means that the binding will not reactively update. If no bindings are bound on any model’s from a query, the query will not be reactively listened to.
62 63 64 65 |
# File 'lib/volt/controllers/model_controller.rb', line 62 def u raise "the 'u' method requires a block" unless block_given? Volt::Computation.run_without_tracking { yield } end |
#yield_html ⇒ Object
yield_html renders the content passed into a tag as a string. You can “‘.watch!“` “`yield_html“` and it will be run again when anything in the template changes.
69 70 71 72 73 74 75 76 77 |
# File 'lib/volt/controllers/model_controller.rb', line 69 def yield_html if (template_path = attrs.content_template_path) @yield_renderer ||= StringTemplateRenderer.new(@volt_app, self, template_path) @yield_renderer.html else # no template, empty string '' end end |