Class: Nested::Resource
- Inherits:
-
Object
- Object
- Nested::Resource
- Defined in:
- lib/nested.rb
Constant Summary collapse
- SERIALIZE =
->(obj, ctrl, resource) do obj end
- FETCH =
->(resource, ctrl) do raise "implement fetch for resource #{resource.name}" unless resource.parent raise "implement fetch for singleton #{resource.name}" if resource.singleton? parent_resource = resource.parent parent_obj = ctrl.instance_variable_get("@#{parent_resource.instance_variable_name}") if resource.name scope = parent_obj.send(resource.name.to_s.pluralize.to_sym) resource.collection? ? scope : scope.where(id: ctrl.params["#{resource.name.to_s.singularize}_id"]).first else parent_obj.where(id: ctrl.params["#{parent_resource.name.to_s.singularize}_id"]).first end end
Instance Attribute Summary collapse
-
#actions ⇒ Object
readonly
Returns the value of attribute actions.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#resources ⇒ Object
readonly
Returns the value of attribute resources.
Instance Method Summary collapse
- #after_fetch(&block) ⇒ Object
- #before_fetch(&block) ⇒ Object
- #child_resource(name, singleton, collection, &block) ⇒ Object
- #collection? ⇒ Boolean
- #create_sinatra_route(method, action, &block) ⇒ Object
- #delete(action = nil, &block) ⇒ Object
- #fetch(&block) ⇒ Object
- #fetcher ⇒ Object
- #get(action = nil, &block) ⇒ Object
-
#initialize(sinatra, name, singleton, collection, parent) ⇒ Resource
constructor
A new instance of Resource.
- #instance_variable_name ⇒ Object
- #many(name, &block) ⇒ Object
- #member? ⇒ Boolean
- #one(name = nil, &block) ⇒ Object
- #parents ⇒ Object
- #post(action = nil, &block) ⇒ Object
- #put(action = nil, &block) ⇒ Object
- #route(args = {}, action = nil) ⇒ Object
- #self_and_parents ⇒ Object
- #serialize(&block) ⇒ Object
- #serializer ⇒ Object
- #sinatra_exec_delete_block(sinatra, &block) ⇒ Object
- #sinatra_exec_get_block(sinatra, &block) ⇒ Object
- #sinatra_exec_post_block(sinatra, &block) ⇒ Object
- #sinatra_exec_put_block(sinatra, &block) ⇒ Object
-
#sinatra_init(sinatra) ⇒ Object
————————–.
- #sinatra_read_json_body(sinatra) ⇒ Object
- #sinatra_response(sinatra) ⇒ Object
- #sinatra_response_create_data(sinatra, response) ⇒ Object
- #sinatra_response_create_error(sinatra, response) ⇒ Object
- #sinatra_response_type(response) ⇒ Object
- #singleton(name, &block) ⇒ Object
- #singleton? ⇒ Boolean
Constructor Details
#initialize(sinatra, name, singleton, collection, parent) ⇒ Resource
Returns a new instance of Resource.
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/nested.rb', line 39 def initialize(sinatra, name, singleton, collection, parent) raise SingletonAndCollectionError.new if singleton && collection raise NameMissingError.new if (singleton || collection) && !name @sinatra = sinatra @name = name @singleton = singleton @collection = collection @parent = parent @resources = [] @actions = [] end |
Instance Attribute Details
#actions ⇒ Object (readonly)
Returns the value of attribute actions.
37 38 39 |
# File 'lib/nested.rb', line 37 def actions @actions end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
37 38 39 |
# File 'lib/nested.rb', line 37 def name @name end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
37 38 39 |
# File 'lib/nested.rb', line 37 def parent @parent end |
#resources ⇒ Object (readonly)
Returns the value of attribute resources.
37 38 39 |
# File 'lib/nested.rb', line 37 def resources @resources end |
Instance Method Details
#after_fetch(&block) ⇒ Object
66 |
# File 'lib/nested.rb', line 66 def after_fetch(&block); @__after_fetch = block; end |
#before_fetch(&block) ⇒ Object
64 |
# File 'lib/nested.rb', line 64 def before_fetch(&block); @__before_fetch = block; end |
#child_resource(name, singleton, collection, &block) ⇒ Object
125 126 127 128 129 |
# File 'lib/nested.rb', line 125 def child_resource(name, singleton, collection, &block) Resource.new(@sinatra, name, singleton, collection, self) .tap{|r| r.instance_eval(&block)} .tap{|r| @resources << r} end |
#collection? ⇒ Boolean
60 61 62 |
# File 'lib/nested.rb', line 60 def collection? @collection == true end |
#create_sinatra_route(method, action, &block) ⇒ Object
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/nested.rb', line 228 def create_sinatra_route(method, action, &block) @actions << {method: method, action: action} resource = self route = resource.route({}, action) puts "sinatra router [#{method}] #{@sinatra.nested_config[:prefix]}#{route}" @sinatra.send(method, route) do content_type :json resource.self_and_parents.reverse.each do |res| res.sinatra_init(self) end resource.send(:"sinatra_exec_#{method}_block", self, &block) resource.sinatra_response(self) end end |
#delete(action = nil, &block) ⇒ Object
107 108 109 |
# File 'lib/nested.rb', line 107 def delete(action=nil, &block) create_sinatra_route :delete, action, &block end |
#fetch(&block) ⇒ Object
65 |
# File 'lib/nested.rb', line 65 def fetch(&block); @__fetch = block; end |
#fetcher ⇒ Object
149 150 151 |
# File 'lib/nested.rb', line 149 def fetcher @__fetch || FETCH end |
#get(action = nil, &block) ⇒ Object
95 96 97 |
# File 'lib/nested.rb', line 95 def get(action=nil, &block) create_sinatra_route :get, action, &(block||proc {}) end |
#instance_variable_name ⇒ Object
131 132 133 134 135 136 137 138 139 |
# File 'lib/nested.rb', line 131 def instance_variable_name if @name @name.to_s.send(collection? ? :pluralize : :singularize).to_sym elsif member? && @parent @parent.name.to_s.singularize.to_sym else nil end end |
#many(name, &block) ⇒ Object
115 116 117 118 |
# File 'lib/nested.rb', line 115 def many(name, &block) raise ManyInManyError.new "do not nest many in many" if collection? child_resource(name, false, true, &block) end |
#member? ⇒ Boolean
56 57 58 |
# File 'lib/nested.rb', line 56 def member? !singleton? && !collection? end |
#one(name = nil, &block) ⇒ Object
120 121 122 123 |
# File 'lib/nested.rb', line 120 def one(name=nil, &block) raise OneWithNameInManyError.new("call one (#{name}) without name argument when nested in a many (#{@name})") if name && collection? child_resource(name, false, false, &block) end |
#parents ⇒ Object
141 142 143 |
# File 'lib/nested.rb', line 141 def parents (@parent ? @parent.parents + [@parent] : []) end |
#post(action = nil, &block) ⇒ Object
99 100 101 |
# File 'lib/nested.rb', line 99 def post(action=nil, &block) create_sinatra_route :post, action, &block end |
#put(action = nil, &block) ⇒ Object
103 104 105 |
# File 'lib/nested.rb', line 103 def put(action=nil, &block) create_sinatra_route :put, action, &block end |
#route(args = {}, action = nil) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/nested.rb', line 69 def route(args={}, action=nil) "".tap do |r| r << @parent.route(args) if @parent if singleton? r << "/" + @name.to_s.singularize elsif collection? r << "/" + @name.to_s.pluralize else if @name r << "/" + @name.to_s.pluralize end r << "/" key = ((@name || @parent.name).to_s.singularize + "_id").to_sym if args.key?(key) r << args[key].to_s else r << ":#{key}" end end r << "/#{action}" if action end end |
#self_and_parents ⇒ Object
145 146 147 |
# File 'lib/nested.rb', line 145 def self_and_parents (self.parents + [self]).reverse end |
#serialize(&block) ⇒ Object
67 |
# File 'lib/nested.rb', line 67 def serialize(&block); @__serialize = block; end |
#serializer ⇒ Object
153 154 155 |
# File 'lib/nested.rb', line 153 def serializer @__serialize || SERIALIZE end |
#sinatra_exec_delete_block(sinatra, &block) ⇒ Object
173 174 175 |
# File 'lib/nested.rb', line 173 def sinatra_exec_delete_block(sinatra, &block) sinatra.instance_exec(self, &block) end |
#sinatra_exec_get_block(sinatra, &block) ⇒ Object
169 170 171 |
# File 'lib/nested.rb', line 169 def sinatra_exec_get_block(sinatra, &block) sinatra.instance_exec(self, &block) end |
#sinatra_exec_post_block(sinatra, &block) ⇒ Object
187 188 189 190 191 |
# File 'lib/nested.rb', line 187 def sinatra_exec_post_block(sinatra, &block) data = sinatra_read_json_body(sinatra) res = sinatra.instance_exec(data, self, &block) sinatra.instance_variable_set("@#{self.instance_variable_name}", res) end |
#sinatra_exec_put_block(sinatra, &block) ⇒ Object
182 183 184 185 |
# File 'lib/nested.rb', line 182 def sinatra_exec_put_block(sinatra, &block) data = sinatra_read_json_body(sinatra) sinatra.instance_exec(data, self, &block) end |
#sinatra_init(sinatra) ⇒ Object
159 160 161 162 163 164 165 166 167 |
# File 'lib/nested.rb', line 159 def sinatra_init(sinatra) @__before_fetch.call(self, sinatra) if @__before_fetch resource_obj = fetcher.call(self, sinatra) puts "set @#{self.instance_variable_name} to #{resource_obj.inspect} for #{sinatra}" sinatra.instance_variable_set("@#{self.instance_variable_name}", resource_obj) @__after_fetch.call(self, sinatra) if @__after_fetch end |
#sinatra_read_json_body(sinatra) ⇒ Object
177 178 179 180 |
# File 'lib/nested.rb', line 177 def sinatra_read_json_body(sinatra) sinatra.request.body.rewind HashWithIndifferentAccess.new JSON.parse(sinatra.request.body.read) end |
#sinatra_response(sinatra) ⇒ Object
197 198 199 200 201 202 203 204 205 |
# File 'lib/nested.rb', line 197 def sinatra_response(sinatra) response = sinatra.instance_variable_get("@#{self.instance_variable_name}") response = self.send(:"sinatra_response_create_#{sinatra_response_type(response)}", sinatra, response) case response when String then response else response.to_json end end |
#sinatra_response_create_data(sinatra, response) ⇒ Object
207 208 209 210 211 212 213 214 215 |
# File 'lib/nested.rb', line 207 def sinatra_response_create_data(sinatra, response) data = if response.respond_to?(:to_a) response.to_a.map{|e| serializer.call(e, sinatra, self)} else serializer.call(response, sinatra, self) end {data: data, ok: true} end |
#sinatra_response_create_error(sinatra, response) ⇒ Object
217 218 219 220 221 222 223 224 225 226 |
# File 'lib/nested.rb', line 217 def sinatra_response_create_error(sinatra, response) errors = response.is_a?(ActiveModel::Errors) ? response : response.errors data = errors.to_hash.inject({}) do |memo, e| memo[e[0]] = e[1][0] memo end {data: data, ok: false} end |
#sinatra_response_type(response) ⇒ Object
193 194 195 |
# File 'lib/nested.rb', line 193 def sinatra_response_type(response) (response.is_a?(ActiveModel::Errors) || (response.respond_to?(:errors) && !response.errors.empty?)) ? :error : :data end |
#singleton(name, &block) ⇒ Object
111 112 113 |
# File 'lib/nested.rb', line 111 def singleton(name, &block) child_resource(name, true, false, &block) end |
#singleton? ⇒ Boolean
52 53 54 |
# File 'lib/nested.rb', line 52 def singleton? @singleton == true end |