wallaby 5.0.1 → 5.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -3
- data/app/assets/images/wallaby/404.png +0 -0
- data/app/assets/images/wallaby/422.png +0 -0
- data/app/assets/images/wallaby/500.png +0 -0
- data/app/assets/javascripts/wallaby/application.js +1 -15
- data/app/assets/javascripts/wallaby/auto_select.js +77 -0
- data/app/assets/javascripts/wallaby/base.js +17 -0
- data/app/assets/javascripts/wallaby/setup.js.erb +60 -0
- data/app/assets/stylesheets/wallaby/application.scss +1 -51
- data/app/assets/stylesheets/wallaby/base/_layout.scss +257 -9
- data/app/assets/stylesheets/wallaby/base/_layout_desktop.scss +53 -0
- data/app/assets/stylesheets/wallaby/base/_mixins.scss +119 -0
- data/app/assets/stylesheets/wallaby/base/_override.scss +10 -0
- data/app/assets/stylesheets/wallaby/base/_vars.scss +72 -2
- data/app/assets/stylesheets/wallaby/base.scss +27 -0
- data/app/assets/stylesheets/wallaby/components/_auto_select.scss +119 -0
- data/app/assets/stylesheets/wallaby/components/_auto_select_desktop.scss +7 -0
- data/app/assets/stylesheets/wallaby/components/_color_square.scss +8 -0
- data/app/assets/stylesheets/wallaby/components/_filters.scss +14 -0
- data/app/assets/stylesheets/wallaby/components/_links.scss +25 -0
- data/app/assets/stylesheets/wallaby/components/_pagination.scss +35 -91
- data/app/assets/stylesheets/wallaby/components/_query.scss +101 -0
- data/app/assets/stylesheets/wallaby/components/_text.scss +6 -6
- data/app/assets/stylesheets/wallaby/pages/_error.scss +108 -0
- data/app/assets/stylesheets/wallaby/pages/_form.scss +40 -0
- data/app/assets/stylesheets/wallaby/pages/_index.scss +193 -0
- data/app/assets/stylesheets/wallaby/pages/_index_desktop.scss +22 -0
- data/app/assets/stylesheets/wallaby/pages/_show.scss +21 -0
- data/app/controllers/wallaby/abstract_resources_controller.rb +334 -0
- data/app/controllers/wallaby/application_controller.rb +45 -15
- data/app/controllers/wallaby/base_controller.rb +30 -0
- data/app/controllers/wallaby/resources_controller.rb +2 -131
- data/app/controllers/wallaby/secure_controller.rb +38 -24
- data/app/routes/wallaby/resources_router.rb +40 -43
- data/app/security/ability.rb +4 -28
- data/app/views/layouts/wallaby/application.html.erb +11 -6
- data/app/views/layouts/wallaby/error.html.erb +26 -4
- data/app/views/wallaby/error.html.erb +11 -0
- data/app/views/wallaby/error.json.jbuilder +8 -0
- data/app/views/wallaby/{shared → resources}/_flash_messages.html.erb +0 -0
- data/app/views/wallaby/resources/_footer.html.erb +1 -0
- data/app/views/wallaby/resources/_form.html.erb +2 -2
- data/app/views/wallaby/resources/_header.html.erb +38 -0
- data/app/views/wallaby/resources/_imodal.html.erb +13 -0
- data/app/views/wallaby/resources/_index_actions.html.erb +4 -1
- data/app/views/wallaby/resources/_index_filters.html.erb +23 -0
- data/app/views/wallaby/resources/_index_pagination.html.erb +63 -0
- data/app/views/wallaby/resources/_index_query.html.erb +23 -0
- data/app/views/wallaby/resources/_logo.html.erb +1 -0
- data/app/views/wallaby/resources/_navs.html.erb +9 -0
- data/app/views/wallaby/resources/_resource_actions.html.erb +3 -3
- data/app/views/wallaby/resources/{shared/_resource_nav.html.erb → _resource_navs.html.erb} +6 -6
- data/app/views/wallaby/resources/_title.html.erb +1 -0
- data/app/views/wallaby/resources/_user_menu.html.erb +5 -0
- data/app/views/wallaby/resources/bad_request.json.jbuilder +7 -0
- data/app/views/wallaby/resources/edit.html.erb +16 -12
- data/app/views/wallaby/resources/form/_belongs_to.html.erb +63 -12
- data/app/views/wallaby/resources/form/_bigint.html.erb +10 -1
- data/app/views/wallaby/resources/form/_bigserial.html.erb +18 -0
- data/app/views/wallaby/resources/form/_binary.html.erb +11 -2
- data/app/views/wallaby/resources/form/_bit.html.erb +10 -1
- data/app/views/wallaby/resources/form/_bit_varying.html.erb +10 -1
- data/app/views/wallaby/resources/form/_blob.html.erb +21 -0
- data/app/views/wallaby/resources/form/_boolean.html.erb +9 -0
- data/app/views/wallaby/resources/form/_box.html.erb +21 -0
- data/app/views/wallaby/resources/form/_cidr.html.erb +13 -1
- data/app/views/wallaby/resources/form/_circle.html.erb +21 -0
- data/app/views/wallaby/resources/form/_citext.html.erb +11 -2
- data/app/views/wallaby/resources/form/_color.html.erb +11 -2
- data/app/views/wallaby/resources/form/_date.html.erb +12 -3
- data/app/views/wallaby/resources/form/_daterange.html.erb +14 -5
- data/app/views/wallaby/resources/form/_datetime.html.erb +12 -3
- data/app/views/wallaby/resources/form/_decimal.html.erb +10 -1
- data/app/views/wallaby/resources/form/_dropdown.html.erb +18 -0
- data/app/views/wallaby/resources/form/_email.html.erb +9 -0
- data/app/views/wallaby/resources/form/_file.html.erb +21 -0
- data/app/views/wallaby/resources/form/_float.html.erb +10 -1
- data/app/views/wallaby/resources/form/_has_and_belongs_to_many.html.erb +53 -7
- data/app/views/wallaby/resources/form/_has_many.html.erb +52 -7
- data/app/views/wallaby/resources/form/_has_one.html.erb +10 -2
- data/app/views/wallaby/resources/form/_hstore.html.erb +12 -5
- data/app/views/wallaby/resources/form/_inet.html.erb +13 -1
- data/app/views/wallaby/resources/form/_int4range.html.erb +11 -2
- data/app/views/wallaby/resources/form/_int8range.html.erb +11 -2
- data/app/views/wallaby/resources/form/_integer.html.erb +10 -1
- data/app/views/wallaby/resources/form/_json.html.erb +13 -6
- data/app/views/wallaby/resources/form/_jsonb.html.erb +13 -6
- data/app/views/wallaby/resources/form/_line.html.erb +21 -0
- data/app/views/wallaby/resources/form/_longblob.html.erb +21 -0
- data/app/views/wallaby/resources/form/_longtext.html.erb +30 -0
- data/app/views/wallaby/resources/form/_lseg.html.erb +21 -0
- data/app/views/wallaby/resources/form/_ltree.html.erb +17 -1
- data/app/views/wallaby/resources/form/_macaddr.html.erb +13 -1
- data/app/views/wallaby/resources/form/_markdown.html.erb +29 -0
- data/app/views/wallaby/resources/form/_mediumblob.html.erb +21 -0
- data/app/views/wallaby/resources/form/_mediumtext.html.erb +30 -0
- data/app/views/wallaby/resources/form/_money.html.erb +10 -1
- data/app/views/wallaby/resources/form/_numrange.html.erb +11 -2
- data/app/views/wallaby/resources/form/_password.html.erb +14 -1
- data/app/views/wallaby/resources/form/_path.html.erb +17 -0
- data/app/views/wallaby/resources/form/_point.html.erb +11 -2
- data/app/views/wallaby/resources/form/_polygon.html.erb +17 -0
- data/app/views/wallaby/resources/form/_serial.html.erb +18 -0
- data/app/views/wallaby/resources/form/_sti.html.erb +18 -0
- data/app/views/wallaby/resources/form/_string.html.erb +14 -1
- data/app/views/wallaby/resources/form/_text.html.erb +11 -2
- data/app/views/wallaby/resources/form/_time.html.erb +12 -3
- data/app/views/wallaby/resources/form/_tinyblob.html.erb +21 -0
- data/app/views/wallaby/resources/form/_tinytext.html.erb +30 -0
- data/app/views/wallaby/resources/form/_tsrange.html.erb +14 -5
- data/app/views/wallaby/resources/form/_tstzrange.html.erb +14 -5
- data/app/views/wallaby/resources/form/_tsvector.html.erb +9 -0
- data/app/views/wallaby/resources/form/_unsigned_bigint.html.erb +18 -0
- data/app/views/wallaby/resources/form/_unsigned_decimal.html.erb +18 -0
- data/app/views/wallaby/resources/form/_unsigned_float.html.erb +18 -0
- data/app/views/wallaby/resources/form/_unsigned_integer.html.erb +18 -0
- data/app/views/wallaby/resources/form/_uuid.html.erb +10 -1
- data/app/views/wallaby/resources/form/_xml.html.erb +11 -5
- data/app/views/wallaby/resources/form.json.jbuilder +5 -0
- data/app/views/wallaby/{core → resources}/home.html.erb +1 -1
- data/app/views/wallaby/resources/index/_belongs_to.html.erb +5 -1
- data/app/views/wallaby/resources/index/_bigint.html.erb +4 -0
- data/app/views/wallaby/resources/index/_bigserial.html.erb +5 -0
- data/app/views/wallaby/resources/index/_binary.html.erb +5 -1
- data/app/views/wallaby/resources/index/_bit.html.erb +4 -0
- data/app/views/wallaby/resources/index/_bit_varying.html.erb +4 -0
- data/app/views/wallaby/resources/index/_blob.html.erb +5 -0
- data/app/views/wallaby/resources/index/_boolean.html.erb +5 -1
- data/app/views/wallaby/resources/index/_box.html.erb +16 -0
- data/app/views/wallaby/resources/index/_cidr.html.erb +5 -1
- data/app/views/wallaby/resources/index/_circle.html.erb +16 -0
- data/app/views/wallaby/resources/index/_citext.html.erb +5 -1
- data/app/views/wallaby/resources/index/_color.html.erb +6 -1
- data/app/views/wallaby/resources/index/_date.html.erb +4 -0
- data/app/views/wallaby/resources/index/_daterange.html.erb +5 -1
- data/app/views/wallaby/resources/index/_datetime.html.erb +5 -1
- data/app/views/wallaby/resources/index/_decimal.html.erb +4 -0
- data/app/views/wallaby/resources/index/_email.html.erb +4 -0
- data/app/views/wallaby/resources/index/_float.html.erb +4 -0
- data/app/views/wallaby/resources/index/_has_and_belongs_to_many.html.erb +6 -2
- data/app/views/wallaby/resources/index/_has_many.html.erb +6 -2
- data/app/views/wallaby/resources/index/_has_one.html.erb +5 -1
- data/app/views/wallaby/resources/index/_hstore.html.erb +6 -2
- data/app/views/wallaby/resources/index/_inet.html.erb +5 -1
- data/app/views/wallaby/resources/index/_int4range.html.erb +4 -0
- data/app/views/wallaby/resources/index/_int8range.html.erb +4 -0
- data/app/views/wallaby/resources/index/_integer.html.erb +4 -0
- data/app/views/wallaby/resources/index/_json.html.erb +5 -2
- data/app/views/wallaby/resources/index/_jsonb.html.erb +5 -2
- data/app/views/wallaby/resources/index/_line.html.erb +16 -0
- data/app/views/wallaby/resources/index/_longblob.html.erb +5 -0
- data/app/views/wallaby/resources/index/_longtext.html.erb +16 -0
- data/app/views/wallaby/resources/index/_lseg.html.erb +16 -0
- data/app/views/wallaby/resources/index/_ltree.html.erb +5 -1
- data/app/views/wallaby/resources/index/_macaddr.html.erb +4 -0
- data/app/views/wallaby/resources/index/_mediumblob.html.erb +5 -0
- data/app/views/wallaby/resources/index/_mediumtext.html.erb +16 -0
- data/app/views/wallaby/resources/index/_money.html.erb +4 -0
- data/app/views/wallaby/resources/index/_numrange.html.erb +4 -0
- data/app/views/wallaby/resources/index/_password.html.erb +9 -0
- data/app/views/wallaby/resources/index/_path.html.erb +16 -0
- data/app/views/wallaby/resources/index/_point.html.erb +4 -0
- data/app/views/wallaby/resources/index/_polygon.html.erb +16 -0
- data/app/views/wallaby/resources/index/_raw.html.erb +9 -0
- data/app/views/wallaby/resources/index/_serial.html.erb +5 -0
- data/app/views/wallaby/resources/index/_sti.html.erb +16 -0
- data/app/views/wallaby/resources/index/_string.html.erb +5 -1
- data/app/views/wallaby/resources/index/_text.html.erb +5 -1
- data/app/views/wallaby/resources/index/_time.html.erb +4 -0
- data/app/views/wallaby/resources/index/_tinyblob.html.erb +5 -0
- data/app/views/wallaby/resources/index/_tinytext.html.erb +16 -0
- data/app/views/wallaby/resources/index/_tsrange.html.erb +5 -1
- data/app/views/wallaby/resources/index/_tstzrange.html.erb +5 -1
- data/app/views/wallaby/resources/index/_tsvector.html.erb +5 -1
- data/app/views/wallaby/resources/index/_unsigned_bigint.html.erb +5 -0
- data/app/views/wallaby/resources/index/_unsigned_decimal.html.erb +5 -0
- data/app/views/wallaby/resources/index/_unsigned_float.html.erb +5 -0
- data/app/views/wallaby/resources/index/_unsigned_integer.html.erb +5 -0
- data/app/views/wallaby/resources/index/_uuid.html.erb +5 -1
- data/app/views/wallaby/resources/index/_xml.html.erb +5 -1
- data/app/views/wallaby/resources/index.csv.erb +26 -0
- data/app/views/wallaby/resources/index.html.erb +47 -59
- data/app/views/wallaby/resources/index.json.jbuilder +5 -0
- data/app/views/wallaby/resources/new.html.erb +12 -11
- data/app/views/wallaby/resources/show/_belongs_to.html.erb +5 -1
- data/app/views/wallaby/resources/show/_bigint.html.erb +4 -0
- data/app/views/wallaby/resources/show/_bigserial.html.erb +5 -0
- data/app/views/wallaby/resources/show/_binary.html.erb +5 -1
- data/app/views/wallaby/resources/show/_bit.html.erb +4 -0
- data/app/views/wallaby/resources/show/_bit_varying.html.erb +4 -0
- data/app/views/wallaby/resources/show/_blob.html.erb +5 -0
- data/app/views/wallaby/resources/show/_boolean.html.erb +5 -1
- data/app/views/wallaby/resources/show/_box.html.erb +9 -0
- data/app/views/wallaby/resources/show/_cidr.html.erb +5 -1
- data/app/views/wallaby/resources/show/_circle.html.erb +9 -0
- data/app/views/wallaby/resources/show/_citext.html.erb +4 -0
- data/app/views/wallaby/resources/show/_color.html.erb +6 -1
- data/app/views/wallaby/resources/show/_date.html.erb +4 -0
- data/app/views/wallaby/resources/show/_daterange.html.erb +4 -0
- data/app/views/wallaby/resources/show/_datetime.html.erb +4 -0
- data/app/views/wallaby/resources/show/_decimal.html.erb +4 -0
- data/app/views/wallaby/resources/show/_email.html.erb +4 -0
- data/app/views/wallaby/resources/show/_float.html.erb +4 -0
- data/app/views/wallaby/resources/show/_has_and_belongs_to_many.html.erb +6 -2
- data/app/views/wallaby/resources/show/_has_many.html.erb +6 -2
- data/app/views/wallaby/resources/show/_has_one.html.erb +5 -1
- data/app/views/wallaby/resources/show/_hstore.html.erb +4 -0
- data/app/views/wallaby/resources/show/_image.html.erb +9 -0
- data/app/views/wallaby/resources/show/_inet.html.erb +5 -1
- data/app/views/wallaby/resources/show/_int4range.html.erb +4 -0
- data/app/views/wallaby/resources/show/_int8range.html.erb +4 -0
- data/app/views/wallaby/resources/show/_integer.html.erb +4 -0
- data/app/views/wallaby/resources/show/_json.html.erb +4 -0
- data/app/views/wallaby/resources/show/_jsonb.html.erb +4 -0
- data/app/views/wallaby/resources/show/_line.html.erb +9 -0
- data/app/views/wallaby/resources/show/_longblob.html.erb +5 -0
- data/app/views/wallaby/resources/show/_longtext.html.erb +5 -0
- data/app/views/wallaby/resources/show/_lseg.html.erb +9 -0
- data/app/views/wallaby/resources/show/_ltree.html.erb +4 -0
- data/app/views/wallaby/resources/show/_macaddr.html.erb +4 -0
- data/app/views/wallaby/resources/show/_mediumblob.html.erb +5 -0
- data/app/views/wallaby/resources/show/_mediumtext.html.erb +5 -0
- data/app/views/wallaby/resources/show/_money.html.erb +4 -0
- data/app/views/wallaby/resources/show/_numrange.html.erb +4 -0
- data/app/views/wallaby/resources/show/_password.html.erb +9 -0
- data/app/views/wallaby/resources/show/_path.html.erb +9 -0
- data/app/views/wallaby/resources/show/_point.html.erb +4 -0
- data/app/views/wallaby/resources/show/_polygon.html.erb +9 -0
- data/app/views/wallaby/resources/show/_raw.html.erb +9 -0
- data/app/views/wallaby/resources/show/_serial.html.erb +5 -0
- data/app/views/wallaby/resources/show/_sti.html.erb +5 -0
- data/app/views/wallaby/resources/show/_string.html.erb +4 -0
- data/app/views/wallaby/resources/show/_text.html.erb +4 -0
- data/app/views/wallaby/resources/show/_time.html.erb +4 -0
- data/app/views/wallaby/resources/show/_tinyblob.html.erb +5 -0
- data/app/views/wallaby/resources/show/_tinytext.html.erb +5 -0
- data/app/views/wallaby/resources/show/_tsrange.html.erb +4 -0
- data/app/views/wallaby/resources/show/_tstzrange.html.erb +4 -0
- data/app/views/wallaby/resources/show/_tsvector.html.erb +4 -0
- data/app/views/wallaby/resources/show/_unsigned_bigint.html.erb +5 -0
- data/app/views/wallaby/resources/show/_unsigned_decimal.html.erb +5 -0
- data/app/views/wallaby/resources/show/_unsigned_float.html.erb +5 -0
- data/app/views/wallaby/resources/show/_unsigned_integer.html.erb +5 -0
- data/app/views/wallaby/resources/show/_uuid.html.erb +4 -0
- data/app/views/wallaby/resources/show/_xml.html.erb +4 -0
- data/app/views/wallaby/resources/show.html.erb +14 -24
- data/app/views/wallaby/resources/show.json.jbuilder +5 -0
- data/config/brakeman.ignore +26 -0
- data/config/locales/wallaby.en.yml +91 -0
- data/config/massa.yml +45 -0
- data/config/rails_best_practices.yml +42 -0
- data/config/routes.rb +29 -23
- data/lib/adaptors/wallaby/active_record/model_decorator/fields_builder/association_builder.rb +39 -0
- data/lib/adaptors/wallaby/active_record/model_decorator/fields_builder/polymorphic_builder.rb +44 -0
- data/lib/adaptors/wallaby/active_record/model_decorator/fields_builder/sti_builder.rb +42 -0
- data/lib/adaptors/wallaby/active_record/model_decorator/fields_builder.rb +41 -94
- data/lib/adaptors/wallaby/active_record/model_decorator/title_field_finder.rb +24 -14
- data/lib/adaptors/wallaby/active_record/model_decorator.rb +118 -64
- data/lib/adaptors/wallaby/active_record/model_finder.rb +44 -15
- data/lib/adaptors/wallaby/active_record/model_pagination_provider.rb +30 -0
- data/lib/adaptors/wallaby/active_record/model_service_provider/normalizer.rb +42 -0
- data/lib/adaptors/wallaby/active_record/model_service_provider/permitter.rb +64 -0
- data/lib/adaptors/wallaby/active_record/model_service_provider/querier/transformer.rb +70 -0
- data/lib/adaptors/wallaby/active_record/model_service_provider/querier.rb +102 -0
- data/lib/adaptors/wallaby/active_record/model_service_provider/validator.rb +29 -0
- data/lib/adaptors/wallaby/active_record/model_service_provider.rb +137 -0
- data/lib/adaptors/wallaby/active_record.rb +4 -1
- data/lib/decorators/wallaby/abstract_resource_decorator.rb +74 -0
- data/lib/decorators/wallaby/resource_decorator.rb +5 -76
- data/lib/errors/wallaby/model_not_found.rb +5 -1
- data/lib/errors/wallaby/not_found.rb +4 -0
- data/lib/errors/wallaby/resource_not_found.rb +5 -1
- data/lib/forms/wallaby/form_builder.rb +42 -19
- data/lib/helpers/wallaby/application_helper.rb +34 -24
- data/lib/helpers/wallaby/base_helper.rb +52 -0
- data/lib/helpers/wallaby/form_helper.rb +40 -16
- data/lib/helpers/wallaby/index_helper.rb +59 -0
- data/lib/helpers/wallaby/links_helper.rb +150 -81
- data/lib/helpers/wallaby/resources_helper.rb +41 -46
- data/lib/helpers/wallaby/secure_helper.rb +36 -19
- data/lib/helpers/wallaby/styling_helper.rb +53 -44
- data/lib/interfaces/wallaby/mode.rb +19 -12
- data/lib/interfaces/wallaby/model_decorator.rb +176 -50
- data/lib/interfaces/wallaby/model_finder.rb +7 -3
- data/lib/interfaces/wallaby/model_pagination_provider.rb +104 -0
- data/lib/interfaces/wallaby/model_service_provider.rb +71 -0
- data/lib/paginators/wallaby/abstract_resource_paginator.rb +23 -0
- data/lib/paginators/wallaby/resource_paginator.rb +6 -0
- data/lib/parsers/wallaby/parser.rb +32 -0
- data/lib/responders/wallaby/abstract_responder.rb +68 -0
- data/lib/responders/wallaby/resources_responder.rb +6 -0
- data/lib/servicers/wallaby/abstract_model_servicer.rb +48 -0
- data/lib/servicers/wallaby/model_servicer.rb +5 -0
- data/lib/services/wallaby/link_options_normalizer.rb +16 -0
- data/lib/services/wallaby/lookup_context_wrapper.rb +23 -30
- data/lib/services/wallaby/map/mode_mapper.rb +19 -0
- data/lib/services/wallaby/map/model_class_collector.rb +41 -0
- data/lib/services/wallaby/map/model_class_mapper.rb +24 -0
- data/lib/services/wallaby/map.rb +76 -39
- data/lib/services/wallaby/partial_renderer.rb +60 -0
- data/lib/services/wallaby/prefixes_builder.rb +54 -0
- data/lib/services/wallaby/sorting/hash_builder.rb +16 -0
- data/lib/services/wallaby/sorting/link_builder.rb +45 -0
- data/lib/services/wallaby/sorting/next_builder.rb +54 -0
- data/lib/services/wallaby/url_for.rb +36 -0
- data/lib/tree/wallaby/node.rb +17 -0
- data/lib/utils/wallaby/utils.rb +67 -22
- data/lib/wallaby/configuration/features.rb +12 -0
- data/lib/wallaby/configuration/metadata.rb +12 -0
- data/lib/wallaby/configuration/models.rb +27 -12
- data/lib/wallaby/configuration/pagination.rb +12 -0
- data/lib/wallaby/configuration/security.rb +55 -24
- data/lib/wallaby/configuration.rb +38 -19
- data/lib/wallaby/engine.rb +84 -39
- data/lib/wallaby/version.rb +1 -1
- data/lib/wallaby.rb +22 -3
- metadata +200 -55
- data/app/assets/javascripts/wallaby/form.js +0 -8
- data/app/assets/stylesheets/wallaby/base/_functions.scss +0 -0
- data/app/assets/stylesheets/wallaby/base/_normalize.scss +0 -0
- data/app/assets/stylesheets/wallaby/base/_reset.scss +0 -0
- data/app/assets/stylesheets/wallaby/components/_forms.scss +0 -53
- data/app/assets/stylesheets/wallaby/components/_nav.scss +0 -19
- data/app/assets/stylesheets/wallaby/components/_tables.scss +0 -78
- data/app/assets/stylesheets/wallaby/form.scss +0 -11
- data/app/controllers/wallaby/core_controller.rb +0 -28
- data/app/views/layouts/wallaby/_footer.html.erb +0 -2
- data/app/views/layouts/wallaby/_header.html.erb +0 -57
- data/app/views/layouts/wallaby/_navs.html.erb +0 -1
- data/app/views/wallaby/errors/access_denied.html.erb +0 -1
- data/app/views/wallaby/errors/not_authenticated.html.erb +0 -1
- data/app/views/wallaby/errors/not_found.html.erb +0 -6
- data/app/views/wallaby/errors/unprocessable_entity.erb +0 -1
- data/config/locales/en.yml +0 -29
- data/lib/adaptors/wallaby/active_record/model_operator/normalizer.rb +0 -44
- data/lib/adaptors/wallaby/active_record/model_operator/permitter.rb +0 -50
- data/lib/adaptors/wallaby/active_record/model_operator/querier.rb +0 -47
- data/lib/adaptors/wallaby/active_record/model_operator/validator.rb +0 -16
- data/lib/adaptors/wallaby/active_record/model_operator.rb +0 -82
- data/lib/errors/wallaby/deprecated.rb +0 -4
- data/lib/errors/wallaby/operation_not_found.rb +0 -4
- data/lib/handlers/wallaby/cached_compiled_erb.rb +0 -14
- data/lib/helpers/wallaby/core_helper.rb +0 -50
- data/lib/helpers/wallaby/paginatable_helper.rb +0 -9
- data/lib/helpers/wallaby/sorting_helper.rb +0 -43
- data/lib/interfaces/wallaby/model_operator.rb +0 -31
- data/lib/services/wallaby/decorator_finder.rb +0 -16
- data/lib/services/wallaby/model_servicer.rb +0 -38
- data/lib/services/wallaby/servicer_finder.rb +0 -5
@@ -1,18 +1,28 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
class ModelDecorator
|
4
|
+
# Try to find the field that can be used as title
|
5
|
+
class TitleFieldFinder
|
6
|
+
TITLE_FIELD_TYPES = %w(string).freeze
|
7
|
+
TITLE_NAMES = %w(name title string text).freeze
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def initialize(model_class, fields)
|
10
|
+
@model_class = model_class
|
11
|
+
@fields = fields
|
12
|
+
end
|
13
|
+
|
14
|
+
def find
|
15
|
+
possible_title_fields = @fields.select do |_field_name, metadata|
|
16
|
+
TITLE_FIELD_TYPES.include? metadata[:type]
|
17
|
+
end
|
18
|
+
target_field = possible_title_fields.values.find do |metadata|
|
19
|
+
TITLE_NAMES.any? { |v| metadata[:name].index v }
|
20
|
+
end
|
21
|
+
target_field ||= possible_title_fields.values.first
|
22
|
+
target_field ||= { name: @model_class.primary_key }
|
23
|
+
target_field[:name]
|
24
|
+
end
|
25
|
+
end
|
13
26
|
end
|
14
|
-
target_field ||= possible_title_fields.values.first
|
15
|
-
target_field ||= { name: @model_class.primary_key }
|
16
|
-
target_field[:name]
|
17
27
|
end
|
18
28
|
end
|
@@ -1,81 +1,135 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
end.with_indifferent_access
|
10
|
-
end
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
# Modal decorator for Active Record
|
4
|
+
class ModelDecorator < ::Wallaby::ModelDecorator
|
5
|
+
# Data types to exclude for index page
|
6
|
+
INDEX_EXCLUSIVE_DATA_TYPES =
|
7
|
+
%w(binary citext hstore json jsonb text tsvector xml).freeze
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
9
|
+
# Data types to exclude for form page
|
10
|
+
FORM_EXCLUSIVE_DATA_TYPES = %w(created_at updated_at).freeze
|
15
11
|
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
# Origin metadata coming from data source.
|
13
|
+
# It needs to be frozen so that we can keep the metadata integrity
|
14
|
+
# @return [Hash]
|
15
|
+
# example:
|
16
|
+
# {
|
17
|
+
# # general field
|
18
|
+
# id: { name: 'id', type: 'integer', label: 'Id', is_origin: true },
|
19
|
+
# # association field
|
20
|
+
# category: {
|
21
|
+
# 'name' => 'category',
|
22
|
+
# 'type' => 'belongs_to',
|
23
|
+
# 'label' => 'Category',
|
24
|
+
# 'is_origin' => true,
|
25
|
+
# 'is_association' => true,
|
26
|
+
# 'is_through' => false,
|
27
|
+
# 'has_scope' => false,
|
28
|
+
# 'foreign_key' => 'category_id',
|
29
|
+
# 'class' => Category
|
30
|
+
# }
|
31
|
+
# }
|
32
|
+
def fields
|
33
|
+
@fields ||= ::ActiveSupport::HashWithIndifferentAccess.new.tap do |hash|
|
34
|
+
# NOTE: There is a chance that people create Active Record class
|
35
|
+
# before they do the migration, so initialising the fields will raise
|
36
|
+
# all kinds of error. Therefore, we need to check the table existence
|
37
|
+
if @model_class.table_exists?
|
38
|
+
hash.merge! general_fields
|
39
|
+
hash.merge! association_fields
|
40
|
+
hash.except!(*foreign_keys_from_associations)
|
41
|
+
end
|
42
|
+
end.freeze
|
43
|
+
end
|
19
44
|
|
20
|
-
|
21
|
-
|
22
|
-
|
45
|
+
# A copy of all the fields for index page
|
46
|
+
# @return [Hash]
|
47
|
+
def index_fields
|
48
|
+
@index_fields ||= Utils.clone fields
|
49
|
+
end
|
23
50
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
51
|
+
# A copy of all the fields for show page
|
52
|
+
# @return [Hash]
|
53
|
+
def show_fields
|
54
|
+
@show_fields ||= Utils.clone fields
|
55
|
+
end
|
30
56
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end.keys
|
37
|
-
end
|
57
|
+
# A copy of all the fields for form page
|
58
|
+
# @return [Hash]
|
59
|
+
def form_fields
|
60
|
+
@form_fields ||= Utils.clone fields
|
61
|
+
end
|
38
62
|
|
39
|
-
|
40
|
-
|
41
|
-
|
63
|
+
# Fields name for index page
|
64
|
+
# @return [Array]
|
65
|
+
def index_field_names
|
66
|
+
@index_field_names ||= begin
|
67
|
+
index_fields.reject do |_field_name, metadata|
|
68
|
+
metadata[:is_association] \
|
69
|
+
|| INDEX_EXCLUSIVE_DATA_TYPES.include?(metadata[:type])
|
70
|
+
end.keys
|
71
|
+
end
|
72
|
+
end
|
42
73
|
|
43
|
-
|
44
|
-
|
45
|
-
|
74
|
+
# Fields name for form page
|
75
|
+
# @return [Array]
|
76
|
+
def form_field_names
|
77
|
+
@form_field_names ||= begin
|
78
|
+
form_fields.reject do |field_name, metadata|
|
79
|
+
field_name == primary_key \
|
80
|
+
|| FORM_EXCLUSIVE_DATA_TYPES.include?(field_name) \
|
81
|
+
|| metadata[:has_scope] || metadata[:is_through]
|
82
|
+
end.keys
|
83
|
+
end
|
84
|
+
end
|
46
85
|
|
47
|
-
|
48
|
-
|
49
|
-
|
86
|
+
# Errors for resource
|
87
|
+
# @return [ActiveModel::Errors]
|
88
|
+
def form_active_errors(resource)
|
89
|
+
resource.errors
|
90
|
+
end
|
50
91
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
92
|
+
# Primary key for the resource
|
93
|
+
# @return [String]
|
94
|
+
def primary_key
|
95
|
+
@model_class.primary_key
|
96
|
+
end
|
55
97
|
|
56
|
-
|
57
|
-
|
58
|
-
|
98
|
+
# To guess the title for resource.
|
99
|
+
# It will go through the fields and try to find out the one that looks
|
100
|
+
# like a name or text to represent this resource. Otherwise, it will fall
|
101
|
+
# back to primary key.
|
102
|
+
# @param resource [Object]
|
103
|
+
# @return [String] the title of given resource
|
104
|
+
def guess_title(resource)
|
105
|
+
resource.public_send title_field_finder.find
|
106
|
+
end
|
59
107
|
|
60
|
-
|
108
|
+
protected
|
61
109
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
keys
|
67
|
-
end
|
68
|
-
end
|
110
|
+
# @see Wallaby::ModelDecorator::FieldsBuilder
|
111
|
+
def field_builder
|
112
|
+
@field_builder ||= FieldsBuilder.new @model_class
|
113
|
+
end
|
69
114
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
115
|
+
# @see Wallaby::ModelDecorator::TitleFieldFinder
|
116
|
+
def title_field_finder
|
117
|
+
@title_field_finder ||=
|
118
|
+
TitleFieldFinder.new @model_class, general_fields
|
119
|
+
end
|
120
|
+
|
121
|
+
delegate :general_fields, :association_fields, to: :field_builder
|
75
122
|
|
76
|
-
|
77
|
-
|
78
|
-
|
123
|
+
# Find out all the foreign keys for a list of fields
|
124
|
+
# @param fields [Hash] metadata of fields
|
125
|
+
# @return [Array] a list of foreign keys
|
126
|
+
def foreign_keys_from_associations(fields = association_fields)
|
127
|
+
fields.each_with_object([]) do |(_field_name, metadata), keys|
|
128
|
+
keys << metadata[:foreign_key] if metadata[:foreign_key]
|
129
|
+
keys << metadata[:polymorphic_type] if metadata[:polymorphic_type]
|
130
|
+
keys
|
131
|
+
end
|
132
|
+
end
|
79
133
|
end
|
80
134
|
end
|
81
135
|
end
|
@@ -1,22 +1,51 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
# Model finder
|
4
|
+
class ModelFinder < ::Wallaby::ModelFinder
|
5
|
+
# @return [Array] a list of ActiveRecord subclasses
|
6
|
+
def all
|
7
|
+
self.class.base.descendants.reject do |model_class|
|
8
|
+
abstract?(model_class) || anonymous?(model_class) \
|
9
|
+
|| schema?(model_class) || habtm?(model_class)
|
10
|
+
end.sort_by(&:to_s)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Base class should be either ApplicationRecord or ActiveRecord::Base
|
14
|
+
def self.base
|
15
|
+
return ::ApplicationRecord if defined? ::ApplicationRecord
|
7
16
|
::ActiveRecord::Base
|
8
17
|
end
|
9
|
-
end
|
10
|
-
end
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
19
|
+
private
|
20
|
+
|
21
|
+
# Is model class abstract?
|
22
|
+
# @param [Class] model class
|
23
|
+
# @return [Boolean]
|
24
|
+
def abstract?(model_class)
|
25
|
+
model_class.abstract_class?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Is model class anonymous?
|
29
|
+
# @param [Class] model class
|
30
|
+
# @return [Boolean]
|
31
|
+
def anonymous?(model_class)
|
32
|
+
model_class.to_s.start_with? '#<Class'
|
33
|
+
end
|
34
|
+
|
35
|
+
# Is model class the shcema migration class?
|
36
|
+
# @param [Class] model class
|
37
|
+
# @return [Boolean]
|
38
|
+
def schema?(model_class)
|
39
|
+
model_class.name == 'ActiveRecord::SchemaMigration'
|
40
|
+
end
|
41
|
+
|
42
|
+
# Check and see if given model class is intermediate class that generated
|
43
|
+
# for has and belongs to many assocation
|
44
|
+
# @param [Class] model class
|
45
|
+
# @return [Boolean]
|
46
|
+
def habtm?(model_class)
|
18
47
|
model_class.name.index('HABTM')
|
19
|
-
end
|
48
|
+
end
|
20
49
|
end
|
21
50
|
end
|
22
51
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
# Model pagination provider
|
4
|
+
class ModelPaginationProvider < ::Wallaby::ModelPaginationProvider
|
5
|
+
# Check if collection has pagination feature
|
6
|
+
# @return [Boolean]
|
7
|
+
def paginatable?
|
8
|
+
@collection.respond_to? :total_count
|
9
|
+
end
|
10
|
+
|
11
|
+
# Total count for the query
|
12
|
+
# @return [Integer]
|
13
|
+
def total
|
14
|
+
@collection.total_count
|
15
|
+
end
|
16
|
+
|
17
|
+
# Page size
|
18
|
+
# @return [Integer]
|
19
|
+
def page_size
|
20
|
+
@params[:per].try(:to_i) || Wallaby.configuration.pagination.page_size
|
21
|
+
end
|
22
|
+
|
23
|
+
# Page number
|
24
|
+
# @return [Integer]
|
25
|
+
def page_number
|
26
|
+
[@params[:page].to_i, 1].max
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
class ModelServiceProvider
|
4
|
+
# Normalizer
|
5
|
+
class Normalizer
|
6
|
+
def initialize(model_decorator)
|
7
|
+
@model_decorator = model_decorator
|
8
|
+
end
|
9
|
+
|
10
|
+
def normalize(params)
|
11
|
+
params.each do |field_name, values|
|
12
|
+
metadata = @model_decorator.fields[field_name] || EMPTY_HASH
|
13
|
+
type = (metadata[:type] || EMPTY_STRING)[/range|point|binary/]
|
14
|
+
next unless type
|
15
|
+
send "normalize_#{type}_values", params, field_name, values
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def normalize_range_values(params, field_name, values)
|
20
|
+
normalized = Array(values).map(&:presence).compact
|
21
|
+
params[field_name] =
|
22
|
+
if normalized.present? && values.length == 2
|
23
|
+
values.first...values.last
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def normalize_point_values(params, field_name, values)
|
28
|
+
normalized = Array(values).map(&:presence).compact
|
29
|
+
params[field_name] =
|
30
|
+
normalized.present? &&
|
31
|
+
values.map(&:to_f) || nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def normalize_binary_values(params, field_name, values)
|
35
|
+
params[field_name] =
|
36
|
+
values.is_a?(::ActionDispatch::Http::UploadedFile) &&
|
37
|
+
values.read || nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
class ModelServiceProvider
|
4
|
+
# Filter the params
|
5
|
+
class Permitter
|
6
|
+
def initialize(model_decorator)
|
7
|
+
@model_decorator = model_decorator
|
8
|
+
end
|
9
|
+
|
10
|
+
def simple_field_names
|
11
|
+
field_names =
|
12
|
+
non_range_fields.keys +
|
13
|
+
belongs_to_fields.map do |_, metadata|
|
14
|
+
[metadata[:foreign_key], metadata[:polymorphic_type]]
|
15
|
+
end.flatten.compact
|
16
|
+
fields = [@model_decorator.primary_key, 'created_at', 'updated_at']
|
17
|
+
field_names.reject { |field_name| fields.include? field_name }
|
18
|
+
end
|
19
|
+
|
20
|
+
def compound_hashed_fields
|
21
|
+
field_names =
|
22
|
+
range_fields.keys +
|
23
|
+
many_association_fields.map { |_, metadata| metadata[:foreign_key] }
|
24
|
+
field_names.each_with_object({}) { |name, hash| hash[name] = [] }
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def non_association_fields
|
30
|
+
@model_decorator
|
31
|
+
.fields.reject { |_, metadata| metadata[:is_association] }
|
32
|
+
end
|
33
|
+
|
34
|
+
def non_range_fields
|
35
|
+
non_association_fields
|
36
|
+
.reject { |_, metadata| /range|point/ =~ metadata[:type] }
|
37
|
+
end
|
38
|
+
|
39
|
+
def range_fields
|
40
|
+
non_association_fields.select do |_, metadata|
|
41
|
+
/range|point/ =~ metadata[:type]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def association_fields
|
46
|
+
@model_decorator.fields.select do |_, metadata|
|
47
|
+
metadata[:is_association] &&
|
48
|
+
!metadata[:has_scope] && !metadata[:is_through]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def many_association_fields
|
53
|
+
association_fields.select { |_, metadata| /many/ =~ metadata[:type] }
|
54
|
+
end
|
55
|
+
|
56
|
+
def belongs_to_fields
|
57
|
+
association_fields.select do |_field_name, metadata|
|
58
|
+
metadata[:type] == 'belongs_to'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
class ModelServiceProvider
|
4
|
+
class Querier
|
5
|
+
# Build up query using the results
|
6
|
+
class Transformer < Parslet::Transform
|
7
|
+
SIMPLE_OPERATORS = {
|
8
|
+
':' => :eq,
|
9
|
+
':=' => :eq,
|
10
|
+
':!' => :not_eq,
|
11
|
+
':!=' => :not_eq,
|
12
|
+
':<>' => :not_eq,
|
13
|
+
':~' => :matches,
|
14
|
+
':^' => :matches,
|
15
|
+
':$' => :matches,
|
16
|
+
':!~' => :does_not_match,
|
17
|
+
':!^' => :does_not_match,
|
18
|
+
':!$' => :does_not_match,
|
19
|
+
':>' => :gt,
|
20
|
+
':>=' => :gteq,
|
21
|
+
':<' => :lt,
|
22
|
+
':<=' => :lteq
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
SEQUENCE_OPERATORS = {
|
26
|
+
':' => :in,
|
27
|
+
':=' => :in,
|
28
|
+
':!' => :not_in,
|
29
|
+
':!=' => :not_in,
|
30
|
+
':<>' => :not_in,
|
31
|
+
':()' => :between,
|
32
|
+
':!()' => :not_between
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
rule keyword: simple(:value) do
|
36
|
+
value.try :to_str
|
37
|
+
end
|
38
|
+
|
39
|
+
rule keyword: sequence(:value) do
|
40
|
+
value.presence.try :map, :to_str
|
41
|
+
end
|
42
|
+
|
43
|
+
rule left: simple(:left), op: simple(:op), right: simple(:right) do
|
44
|
+
oped = op.try :to_str
|
45
|
+
operator = SIMPLE_OPERATORS[oped]
|
46
|
+
next unless operator
|
47
|
+
lefted = left.try :to_str
|
48
|
+
convert = case oped
|
49
|
+
when ':~', ':!~' then "%#{right}%"
|
50
|
+
when ':^', ':!^' then "#{right}%"
|
51
|
+
when ':$', ':!$' then "%#{right}"
|
52
|
+
end
|
53
|
+
{ left: lefted, op: operator, right: convert || right }
|
54
|
+
end
|
55
|
+
|
56
|
+
rule left: simple(:left), op: simple(:op), right: sequence(:right) do
|
57
|
+
oped = op.try :to_str
|
58
|
+
operator = SEQUENCE_OPERATORS[oped]
|
59
|
+
next unless operator
|
60
|
+
lefted = left.try :to_str
|
61
|
+
convert = if %w(:() :!()).include?(oped)
|
62
|
+
Range.new right.try(:first), right.try(:last)
|
63
|
+
end
|
64
|
+
{ left: lefted, op: operator, right: convert || right }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
class ModelServiceProvider
|
4
|
+
# Query builder
|
5
|
+
class Querier
|
6
|
+
TEXT_FIELDS = %w(string text citext).freeze
|
7
|
+
|
8
|
+
def initialize(model_decorator)
|
9
|
+
@model_decorator = model_decorator
|
10
|
+
@model_class = @model_decorator.model_class
|
11
|
+
end
|
12
|
+
|
13
|
+
def search(params)
|
14
|
+
filter_name, keywords, field_queries = extract params
|
15
|
+
scope = filtered_by filter_name
|
16
|
+
query = text_search keywords
|
17
|
+
query = field_search field_queries, query
|
18
|
+
scope.where query
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def parser
|
24
|
+
@parser ||= Parser.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def transformer
|
28
|
+
@transformer ||= Transformer.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def table
|
32
|
+
@model_class.arel_table
|
33
|
+
end
|
34
|
+
|
35
|
+
def extract(params)
|
36
|
+
expressions = to_expressions params
|
37
|
+
keywords = expressions.select { |v| v.is_a? String }
|
38
|
+
field_queries = expressions.select { |v| v.is_a? Hash }
|
39
|
+
filter_name = params[:filter]
|
40
|
+
[filter_name, keywords, field_queries]
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_expressions(params)
|
44
|
+
parsed = parser.parse(params[:q] || EMPTY_STRING)
|
45
|
+
converted = transformer.apply parsed
|
46
|
+
converted.is_a?(Array) ? converted : [converted]
|
47
|
+
end
|
48
|
+
|
49
|
+
def filtered_by(filter_name)
|
50
|
+
valid_filter_name =
|
51
|
+
Utils.find_filter_name(filter_name, @model_decorator.filters)
|
52
|
+
scope = find_scope(valid_filter_name)
|
53
|
+
if scope.blank? then unscoped
|
54
|
+
elsif scope.respond_to?(:call) then @model_class.instance_exec(&scope)
|
55
|
+
elsif @model_class.respond_to?(scope)
|
56
|
+
@model_class.public_send(scope)
|
57
|
+
else unscoped
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_scope(filter_name)
|
62
|
+
filter = @model_decorator.filters[filter_name] || {}
|
63
|
+
filter[:scope] || filter_name
|
64
|
+
end
|
65
|
+
|
66
|
+
def unscoped
|
67
|
+
@model_class.where nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def text_search(keywords, query = nil)
|
71
|
+
return query if keywords.blank?
|
72
|
+
text_fields.each do |field_name|
|
73
|
+
sub_query = nil
|
74
|
+
keywords.each do |keyword|
|
75
|
+
exp = table[field_name].matches("%#{keyword}%")
|
76
|
+
sub_query = sub_query.try(:and, exp) || exp
|
77
|
+
end
|
78
|
+
query = query.try(:or, sub_query) || sub_query
|
79
|
+
end
|
80
|
+
query
|
81
|
+
end
|
82
|
+
|
83
|
+
def field_search(field_queries, query)
|
84
|
+
field_queries.each do |exp|
|
85
|
+
next unless @model_decorator.fields[exp[:left]]
|
86
|
+
sub_query = table[exp[:left]].public_send(exp[:op], exp[:right])
|
87
|
+
query = query.try(:and, sub_query) || sub_query
|
88
|
+
end
|
89
|
+
query
|
90
|
+
end
|
91
|
+
|
92
|
+
def text_fields
|
93
|
+
index_field_names = @model_decorator.index_field_names.map(&:to_s)
|
94
|
+
@model_decorator.fields.select do |field_name, metadata|
|
95
|
+
index_field_names.include?(field_name) &&
|
96
|
+
TEXT_FIELDS.include?(metadata[:type].to_s)
|
97
|
+
end.keys
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Wallaby
|
2
|
+
class ActiveRecord
|
3
|
+
class ModelServiceProvider
|
4
|
+
# Validator
|
5
|
+
class Validator
|
6
|
+
def initialize(model_decorator)
|
7
|
+
@model_decorator = model_decorator
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?(resource)
|
11
|
+
resource.attributes.each do |field_name, values|
|
12
|
+
metadata = @model_decorator.fields[field_name]
|
13
|
+
next if valid_range_type? values, metadata
|
14
|
+
resource.errors.add field_name, 'required for range data'
|
15
|
+
end
|
16
|
+
resource.errors.blank?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def valid_range_type?(values, metadata)
|
22
|
+
!metadata \
|
23
|
+
|| !%w(daterange tsrange tstzrange).include?(metadata[:type]) \
|
24
|
+
|| !values.try(:any?, &:blank?)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|