Module: PushRoute::ClassMethods
- Defined in:
- lib/push_routes/push_route.rb
Instance Method Summary collapse
-
#add_belongs_to_trigger(action, model, type = :after_save) ⇒ Object
If you have a route like /room/:id/messages where Message belongs_to room you can use add_belongs_to_trigger :index, Message It will look at the url and try to add a trigger on Message save triggering the id as Message.room.id.
- #add_id_trigger(action, model, id_name, type = :after_save) ⇒ Object
- #add_show_trigger(action) ⇒ Object
-
#add_trigger(action, model, type, trigger_function = nil) ⇒ Object
Sets a trigger for pushing updates function should return true to trigger update of the route; if the route requires params to resolve (i.e /users/:id/files) the params should be returned as a hash.
-
#enable_push_route(action, route = nil) ⇒ Object
TODO: if not route already make, make it; set association between route(s) and action test method aliasing, perhaps can still do caching explicitly, or maybe just expiring caches properly; ignore caches for now.
- #instance_trigger?(method_sym) ⇒ Boolean
-
#method_missing(method_sym, *arguments, &block) ⇒ Object
If it’s defined as an instance method and not a static method we’ll define a static method which wraps the functinality While this seems crazy, ActionMailer does this so there’s precident.
-
#model ⇒ Object
TODO: check for full class depth or shallow depth i.e.
-
#respond_to_missing?(method_sym, include_private = false) ⇒ Boolean
Overriding respond_to_missing to allow our method_missing override to behave properly.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_sym, *arguments, &block) ⇒ Object
If it’s defined as an instance method and not a static method we’ll define a static method which wraps the functinality While this seems crazy, ActionMailer does this so there’s precident
80 81 82 83 84 85 86 |
# File 'lib/push_routes/push_route.rb', line 80 def method_missing(method_sym, *arguments, &block) if instance_trigger?(method_sym) new.send(method_sym, *arguments, &block) else super end end |
Instance Method Details
#add_belongs_to_trigger(action, model, type = :after_save) ⇒ Object
If you have a route like /room/:id/messages where Message belongs_to room you can use add_belongs_to_trigger :index, Message It will look at the url and try to add a trigger on Message save triggering the id as Message.room.id
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/push_routes/push_route.rb', line 170 def add_belongs_to_trigger(action, model, type = :after_save) enable_push_route action unless push_routes[action] url = push_routes[action] warn "Push Routes WARNING: Url #{url.inspect} contains too many params" if url.param_associations.count > 1 warn "Push Routes WARNING: Url #{url.inspect} contains not enough notated params" if url.param_associations.count > 1 sym = url.param_associations.first[1].singularize.to_sym if model.table_exists? if model&.send(:new)&.respond_to?(sym) add_trigger(action, model, type) { |object| {id: object.send(sym)&.id} } else warn "Push Routes WARNING: #{model} does not respond to #{sym} in belongs_to trigger" end else warn("Push Routes WARNING: no table exists for #{model}") end end |
#add_id_trigger(action, model, id_name, type = :after_save) ⇒ Object
162 163 164 |
# File 'lib/push_routes/push_route.rb', line 162 def add_id_trigger(action, model, id_name, type = :after_save) add_trigger(action, model, type) { |object| {id: object.send(id_name)} } end |
#add_show_trigger(action) ⇒ Object
187 188 189 190 191 192 193 |
# File 'lib/push_routes/push_route.rb', line 187 def add_show_trigger(action) if self.model add_id_trigger(action, self.model, :id) else warn "Push Routes WARNING: No model found for #{controller_path}" end end |
#add_trigger(action, model, type, trigger_function = nil) ⇒ Object
Sets a trigger for pushing updates function should return true to trigger update of the route; if the route requires params to resolve (i.e /users/:id/files) the params should be returned as a hash. Return false or nil to not trigger an update
106 107 108 109 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 143 144 145 146 147 148 149 150 |
# File 'lib/push_routes/push_route.rb', line 106 def add_trigger(action, model, type, trigger_function = nil) enable_push_route action unless push_routes[action] # Get get the callback passed in if (!trigger_function and block_given?) # Block only # Note Proc.new gets the passed in block without instantiating an extra proc # See http://mudge.name/2011/01/26/passing-blocks-in-ruby-without-block.html callback = Proc.new elsif trigger_function && trigger_function.is_a?(Proc) # Proc passed callback = trigger_function elsif trigger_function #&& !trigger_function.is_a?(Proc) implied here # Symbol passed trigger_symbols << trigger_function callback = lambda { |e| self.send(trigger_function, e) } else #default value callback = Proc.new { true } end if [:after_commit, :after_save, :after_update, :after_create, :after_destroy].include? type this = self func = lambda do |e| result = callback.call(e) if (result) result = [result] unless result.kind_of?(Array) result.each do |params| update_path = this.push_routes[action].notification_string(params) msg = {channel: update_path, type: "", data: "placeholder"} begin #TODO: Abstract away redis server as a transport #This try catch repetition is bad PushRoutes.redis.publish 'rt-change', msg.to_json rescue Redis::CannotConnectError => e warn "PushRoutes cannot reach the redis server" end end end end model.send(type, func) else raise ArgumentError.new("Invalid trigger type") end end |
#enable_push_route(action, route = nil) ⇒ Object
TODO: if not route already make, make it; set association between route(s) and action test method aliasing, perhaps can still do caching explicitly, or maybe just expiring caches properly; ignore caches for now
maybe just internal whisper pub sub with a routing adapter also pull out seperate class for each push route to store routes and triggers Maybe rails magic on for trigger function names
42 43 44 45 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 |
# File 'lib/push_routes/push_route.rb', line 42 def enable_push_route(action, route = nil) matched_url = nil Rails.application.routes.routes.each do |e| if e.defaults[:controller] == self.controller_path && e.defaults[:action] == action.to_s unless matched_url matched_url = PushRoutes::PushRouteUrl.new(e) else raise ArgumentError.new("Duplicate route for push route controller") end end end #If a route exists and one is provided, make sure they are compatable if matched_url and route raise ArgumentError.new("Provided route does not match pre-existing route") unless (matched_url.matches(route)) url = matched_url elsif route and !matched_url #There was no pre-existing route found and a route was specified # Add this route to the list of live routes url = PushRoutes::PushRouteUrl.new(route) elsif !route and matched_url #Matched one route only, we're good url = matched_url else #No route and no match raise ArgumentError.new("No route found and no route provided") end if push_routes[action] raise ArgumentError.new("Push Route enabled twice") else push_routes[action] = url end end |
#instance_trigger?(method_sym) ⇒ Boolean
93 94 95 |
# File 'lib/push_routes/push_route.rb', line 93 def instance_trigger?(method_sym) trigger_symbols.include?(method_sym) && instance_methods.include?(method_sym) end |
#model ⇒ Object
TODO: check for full class depth or shallow depth i.e. Api2::VitalsController
153 154 155 156 157 158 159 160 |
# File 'lib/push_routes/push_route.rb', line 153 def model #Note: const_defined is unrelialbe due to rails auto_loading, model might not be loaded begin Object.const_get(controller_path.classify) rescue nil end end |
#respond_to_missing?(method_sym, include_private = false) ⇒ Boolean
Overriding respond_to_missing to allow our method_missing override to behave properly
89 90 91 |
# File 'lib/push_routes/push_route.rb', line 89 def respond_to_missing?(method_sym, include_private = false) instance_trigger?(method_sym) || super end |