Class: E
- Inherits:
-
Object
- Object
- E
- Includes:
- EL::ContentHelpers, EL::TagFactory
- Defined in:
- lib/el/crud.rb,
lib/el/cache.rb,
lib/el/assets.rb,
lib/el/tag_factory.rb,
lib/el/content_helpers.rb
Constant Summary collapse
- E__CRUD__AUTH_TEST_PAYLOAD_KEY =
"E__CRUD__AUTH_TEST_PAYLOAD_#{rand(2**64)}".freeze
Class Method Summary collapse
-
.crudify(resource, *path_or_opts, &proc) ⇒ Object
(also: crud)
automatically creates POST/PUT/DELETE actions and map them to corresponding methods of given resource, so sending a POST request to the controller resulting in creating new object of given resource.
Instance Method Summary collapse
- #assets(*args, &proc) ⇒ Object
- #assets_mapper(*args, &proc) ⇒ Object
- #cache(*a, &b) ⇒ Object
- #cache_pool ⇒ Object
- #clear_cache!(*a) ⇒ Object
-
#link_to(*args, &proc) ⇒ Object
build a HTML <a> tag.
-
#link_to!(*args, &proc) ⇒ Object
same as
link_toexcept it wont escape the anchor.
Methods included from EL::ContentHelpers
#capture_html, #content_for, #content_for?, #yield_content
Methods included from EL::TagFactory
#comment_tag, #comment_tag!, #css_tag, #doctype_tag, #js_tag
Class Method Details
.crudify(resource, *path_or_opts, &proc) ⇒ Object Also known as: crud
automatically creates POST/PUT/DELETE actions and map them to corresponding methods of given resource, so sending a POST request to the controller resulting in creating new object of given resource. PUT/PATCH requests will update objects by given id. DELETE requests will delete objects by given id.
32 33 34 35 36 37 38 39 40 41 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 76 77 78 79 80 81 82 83 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 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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/el/crud.rb', line 32 def crudify resource, *path_or_opts, &proc opts = path_or_opts.last.is_a?(Hash) ? path_or_opts.pop : {} if opts[:exclude] opts[:exclude] = [ opts[:exclude] ] unless opts[:exclude].is_a?(Array) else opts[:exclude] = [] end path = path_or_opts.first action = '%s_' << (path || :index).to_s orm = :ar if resource.respond_to?(:arel_table) orm = :dm if resource.respond_to?(:storage_name) orm = :sq if resource.respond_to?(:db_schema) orm_map = { ar: { get: :find, put: :update_attributes, patch: :update_attributes }, sq: { get: :[] } }[orm] || {} resource_method = { get: opts.fetch(:get, orm_map[:get] || :get), put: opts.fetch(:put, orm_map[:put] || :update), post: opts.fetch(:post, :create), patch: opts.fetch(:patch, orm_map[:patch] || :update), delete: opts.fetch(:delete, :destroy), } proc_accept_object, proc_accept_errors = nil if proc proc_accept_object = proc.arity > 0 proc_accept_errors = proc.arity > 1 end pkey = opts[:pkey] || :id join_with = opts[:join_with] || ', ' halt_with = opts[:halt_with] || 500 presenter = lambda do |controller_instance, obj, err| # extracting errors, if any errors = nil if err || (obj.respond_to?(:errors) && (err = obj.errors) && err.respond_to?(:size) && err.size > 0) if err.respond_to?(:join) errors = err else if err.respond_to?(:each_pair) # seems error is a Hash # some objects may respond to `each_pair` but not respond to `inject`, # so using trivial looping to extract error messages. errors = [] err.each_pair do |k,v| # usually DataMapper returns errors in the following format: # { :property => ['error 1', 'error 2'] } # flatten is here just in case we get nested arrays. error = v.is_a?(Array) ? v.flatten.join(join_with) : v.to_s errors << '%s: %s' % [k, error] end elsif err.respond_to?(:to_a) # not Array nor Hash, but convertible to Array # converting error to Array and joining errors = err.to_a elsif err.is_a?(String) errors = [err] else errors = [err.inspect] end end end errors && errors = controller_instance.escape_html(errors.join(join_with)) if proc if errors && opts[:halt_on_errors] controller_instance.halt halt_with, errors end proc_args = [] proc_args = [obj] if proc_accept_object proc_args = [obj, errors] if proc_accept_errors controller_instance.instance_exec(*proc_args, &proc) else if errors # no proc given, so halting when some errors occurring controller_instance.styled_halt halt_with, errors else # no proc given and no errors detected, # so extracting and returning object's pkey. # if no pkey given and object does not respond to :id nor to :[], # returning object as is. if obj.respond_to?(:[]) && obj.respond_to?(:has_key?) obj.has_key?(pkey) ? obj[pkey] : obj elsif obj.respond_to?(pkey) obj.send(pkey) else obj end end end end fetch_object = lambda do |controller_instance, id| obj, err = nil begin id = id.to_i if id =~ /\A\d+\Z/ obj = resource.send(resource_method[:get], id) || controller_instance.halt(404, 'object with ID %s not found' % controller_instance.escape_html(id)) rescue => e err = e. end [obj, err] end create_object = lambda do |controller_instance| obj, err = nil begin data = controller_instance.params.reject { |k,v| opts[:exclude].include?(k) } unless data.has_key?(E__CRUD__AUTH_TEST_PAYLOAD_KEY) obj = resource.send(resource_method[:post], data) end rescue => e err = e. end [obj, err] end update_object = lambda do |controller_instance, request_method, id| obj, err = nil begin obj, err = fetch_object.call(controller_instance, id) unless err data = controller_instance.params.reject { |k,v| opts[:exclude].include?(k) } obj.send(resource_method[request_method], data) end rescue => e err = e. end [obj, err] end # fetching object by given id # and calling #destroy(or whatever in options for delete) on it # # @return [String] empty string delete_object = lambda do |id| err = nil begin obj, err = fetch_object.call(self, id) unless err meth = resource_method[:delete] if obj.respond_to?(meth) obj.send(meth) else err = '%s does not respond to %s' % [obj.inspect, escape_html(meth)] end end rescue => e err = e. end [nil, err] end = lambda do |controller_instance| EConstants::HTTP__REQUEST_METHODS.reject do |rm| next if rm == 'OPTIONS' args = rm == 'POST' ? [{E__CRUD__AUTH_TEST_PAYLOAD_KEY => 'true'}] : [E__CRUD__AUTH_TEST_PAYLOAD_KEY] s,h,b = controller_instance.invoke(action % rm.downcase, *args) do |env| env.update EConstants::ENV__REQUEST_METHOD => rm end s == EConstants::STATUS__PROTECTED end.join(', ') end self.class_exec do define_method action % :get do |id| presenter.call self, *fetch_object.call(self, id) end define_method action % :head do |id| presenter.call self, *fetch_object.call(self, id) end define_method action % :post do presenter.call self, *create_object.call(self) end [:put, :patch].each do |request_method| define_method action % request_method do |id| presenter.call self, *update_object.call(self, request_method, id) end end define_method action % :delete do |id| presenter.call self, *delete_object.call(id) end define_method action % :options do .call self end end end |
Instance Method Details
#assets(*args, &proc) ⇒ Object
73 74 75 |
# File 'lib/el/assets.rb', line 73 def assets *args, &proc app.assets *args, &proc end |
#assets_mapper(*args, &proc) ⇒ Object
77 78 79 |
# File 'lib/el/assets.rb', line 77 def assets_mapper *args, &proc EL::AssetsMapper.new *args, &proc end |
#cache(*a, &b) ⇒ Object
2 |
# File 'lib/el/cache.rb', line 2 def cache(*a, &b); app.cache(*a, &b); end |
#cache_pool ⇒ Object
4 |
# File 'lib/el/cache.rb', line 4 def cache_pool; app.cache_pool; end |
#clear_cache!(*a) ⇒ Object
3 |
# File 'lib/el/cache.rb', line 3 def clear_cache!(*a); app.clear_cache!(*a); end |
#link_to(*args, &proc) ⇒ Object
the anchor will be HTML escaped
build a HTML <a> tag.
if first param is a valid action, the URL of given action will be used. action accepted as a symbol or a string representing action name and format. action can also be passed in deRESTified form, eg. :read instead of :post_read
if nil passed as first argument, a void link will be created
anchor can be passed via second argument. if it is missing, the link will be used as anchor anchor can also be passed as a block
attributes can be passed as a hash via last argument
170 171 172 173 |
# File 'lib/el/tag_factory.rb', line 170 def link_to *args, &proc '<a href="%s"%s>%s</a>' % EUtils.requisites_for_link_to(true, self.class, *args, &proc) end |
#link_to!(*args, &proc) ⇒ Object
same as link_to except it wont escape the anchor
176 177 178 179 |
# File 'lib/el/tag_factory.rb', line 176 def link_to! *args, &proc '<a href="%s"%s>%s</a>' % EUtils.requisites_for_link_to(false, self.class, *args, &proc) end |