Class: Volt::ModelController

Inherits:
Object
  • Object
show all
Includes:
Actions, ReactiveAccessors
Defined in:
lib/volt/controllers/model_controller.rb

Direct Known Subclasses

NoticesController

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Actions

included, #run_actions, #stop_chain

Methods included from ReactiveAccessors

#__reactive_dependency_get, included

Constructor Details

#initialize(*args) ⇒ ModelController

Returns a new instance of ModelController.



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/volt/controllers/model_controller.rb', line 103

def initialize(*args)
  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
    if attrs.respond_to?(:model)
      self.model = attrs.locals[:model]
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object



219
220
221
222
223
224
225
226
227
# File 'lib/volt/controllers/model_controller.rb', line 219

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

#attrsObject

Returns the value of attribute attrs.



101
102
103
# File 'lib/volt/controllers/model_controller.rb', line 101

def attrs
  @attrs
end

#sectionObject

The section is assigned a reference to a “DomSection” which has the dom for the controllers view.



14
15
16
# File 'lib/volt/controllers/model_controller.rb', line 14

def section
  @section
end

Class Method Details

.model(val) ⇒ Object



41
42
43
# File 'lib/volt/controllers/model_controller.rb', line 41

def self.model(val)
  @default_model = val
end

.new(*args, &block) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/volt/controllers/model_controller.rb', line 90

def self.new(*args, &block)
  inst = allocate

  inst.model = @default_model if @default_model

  # In MRI initialize is private for some reason, so call it with send
  inst.send(:initialize, *args, &block)

  inst
end

Instance Method Details

#channelObject



158
159
160
# File 'lib/volt/controllers/model_controller.rb', line 158

def channel
  $page.channel
end

#containerObject

Container returns the node that is parent to all nodes in the section.



20
21
22
# File 'lib/volt/controllers/model_controller.rb', line 20

def container
  section.container_node
end

#controllerObject



166
167
168
# File 'lib/volt/controllers/model_controller.rb', line 166

def controller
  @controller ||= Model.new
end

#cookiesObject



150
151
152
# File 'lib/volt/controllers/model_controller.rb', line 150

def cookies
  $page.cookies
end

#dom_nodesObject



24
25
26
# File 'lib/volt/controllers/model_controller.rb', line 24

def dom_nodes
  section.range
end

#flashObject



138
139
140
# File 'lib/volt/controllers/model_controller.rb', line 138

def flash
  $page.flash
end

#go(url) ⇒ Object



115
116
117
118
119
# File 'lib/volt/controllers/model_controller.rb', line 115

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.

Returns:



181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/volt/controllers/model_controller.rb', line 181

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

#local_storeObject



146
147
148
# File 'lib/volt/controllers/model_controller.rb', line 146

def local_store
  $page.local_store
end

#modelObject



79
80
81
82
83
84
85
86
87
88
# File 'lib/volt/controllers/model_controller.rb', line 79

def model
  model = self.current_model

  # If the model is a proc, call it now
  if model && model.is_a?(Proc)
    model = model.call
  end

  model
end

#model=(val) ⇒ Object

Sets the current model on this controller



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
# File 'lib/volt/controllers/model_controller.rb', line 46

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 self.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

#pageObject



130
131
132
# File 'lib/volt/controllers/model_controller.rb', line 130

def page
  $page.page
end

#paramsObject



142
143
144
# File 'lib/volt/controllers/model_controller.rb', line 142

def params
  $page.params
end

#raw(str) ⇒ Object

Raw marks a string as html safe, so bindings can be rendered as html. With great power comes great responsibility.



205
206
207
208
# File 'lib/volt/controllers/model_controller.rb', line 205

def raw(str)
  str = str.to_s unless str.is_a?(String)
  str.html_safe
end

#redirect_to(url) ⇒ Object

Change the url



122
123
124
125
126
127
128
# File 'lib/volt/controllers/model_controller.rb', line 122

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



194
195
196
197
198
199
200
201
# File 'lib/volt/controllers/model_controller.rb', line 194

def (message="You must login to access this area.")
  unless Volt.current_user_id
    flash._notices << message
    go '/login'

    stop_chain
  end
end

#respond_to?(method_name) ⇒ Boolean

Check if this controller responds_to method, or the model

Returns:



211
212
213
214
215
216
217
# File 'lib/volt/controllers/model_controller.rb', line 211

def respond_to?(method_name)
  super || begin
    model = self.model

    model.respond_to?(method_name) if model
  end
end

#storeObject



134
135
136
# File 'lib/volt/controllers/model_controller.rb', line 134

def store
  $page.store
end

#tasksObject



162
163
164
# File 'lib/volt/controllers/model_controller.rb', line 162

def tasks
  $page.tasks
end

#urlObject



154
155
156
# File 'lib/volt/controllers/model_controller.rb', line 154

def url
  $page.url
end

#url_for(params) ⇒ Object



170
171
172
# File 'lib/volt/controllers/model_controller.rb', line 170

def url_for(params)
  $page.url.url_for(params)
end

#url_with(params) ⇒ Object



174
175
176
# File 'lib/volt/controllers/model_controller.rb', line 174

def url_with(params)
  $page.url.url_with(params)
end

#yield_htmlObject

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.



30
31
32
33
34
35
36
37
38
39
# File 'lib/volt/controllers/model_controller.rb', line 30

def yield_html
  if (template_path = attrs.content_template_path)
    # TODO: Don't use $page global
    @yield_renderer ||= StringTemplateRenderer.new($page, self, template_path)
    @yield_renderer.html
  else
    # no template, empty string
    ''
  end
end