avo 0.2.1 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +49 -48
- data/Gemfile.lock +19 -2
- data/README.md +33 -54
- data/app/controllers/avo/application_controller.rb +34 -1
- data/app/controllers/avo/filters_controller.rb +19 -0
- data/app/controllers/avo/relations_controller.rb +34 -0
- data/app/controllers/avo/resource_overview_controller.rb +14 -7
- data/app/controllers/avo/resources_controller.rb +66 -142
- data/app/controllers/avo/search_controller.rb +55 -0
- data/app/helpers/avo/application_helper.rb +6 -2
- data/app/views/layouts/avo/_javascript.html.erb +1 -0
- data/app/views/layouts/avo/application.html.erb +34 -17
- data/app/views/partials/_footer.html.erb +1 -1
- data/app/views/partials/_header.html.erb +1 -1
- data/avo.gemspec +18 -4
- data/config/credentials.yml.enc +1 -0
- data/config/routes.rb +11 -7
- data/lib/avo.rb +2 -0
- data/lib/avo/app/app.rb +18 -29
- data/lib/avo/app/authorization_service.rb +40 -0
- data/lib/avo/app/fields/has_and_belongs_to_many.rb +1 -0
- data/lib/avo/app/fields/has_many.rb +1 -0
- data/lib/avo/app/fields/id_field.rb +4 -4
- data/lib/avo/app/licensing/community_license.rb +4 -0
- data/lib/avo/app/licensing/hq.rb +85 -0
- data/lib/avo/app/licensing/license.rb +48 -0
- data/lib/avo/app/licensing/license_manager.rb +25 -0
- data/lib/avo/app/licensing/null_license.rb +12 -0
- data/lib/avo/app/licensing/pro_license.rb +9 -0
- data/lib/avo/app/resource.rb +31 -12
- data/lib/avo/configuration.rb +14 -0
- data/lib/avo/engine.rb +1 -1
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/initializer.rb +2 -0
- data/lib/generators/avo/templates/views/_footer.html.erb +1 -1
- data/lib/generators/avo/templates/views/_header.html.erb +1 -1
- data/lib/generators/avo/templates/views/_scripts.html.erb +0 -0
- data/public/avo-packs/css/application-73e568bc.css +3 -0
- data/public/avo-packs/css/application-73e568bc.css.br +0 -0
- data/public/avo-packs/css/application-73e568bc.css.gz +0 -0
- data/public/avo-packs/js/application-044386b1f6fe7a8dcb9f.js +3 -0
- data/public/avo-packs/js/{application-8071f9a0f167bb82b39d.js.LICENSE.txt → application-044386b1f6fe7a8dcb9f.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-044386b1f6fe7a8dcb9f.js.br +0 -0
- data/public/avo-packs/js/application-044386b1f6fe7a8dcb9f.js.gz +0 -0
- data/public/avo-packs/js/application-044386b1f6fe7a8dcb9f.js.map +1 -0
- data/public/avo-packs/js/application-044386b1f6fe7a8dcb9f.js.map.br +0 -0
- data/public/avo-packs/js/application-044386b1f6fe7a8dcb9f.js.map.gz +0 -0
- data/public/avo-packs/manifest.json +8 -6
- data/public/avo-packs/manifest.json.br +0 -0
- data/public/avo-packs/manifest.json.gz +0 -0
- data/public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg +1 -0
- data/public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg.br +0 -0
- data/public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg.gz +0 -0
- data/public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg +1 -0
- data/public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg.br +0 -0
- data/public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg.gz +0 -0
- metadata +70 -25
- data/public/avo-packs/css/application-64b0f124.css +0 -3
- data/public/avo-packs/css/application-64b0f124.css.br +0 -0
- data/public/avo-packs/css/application-64b0f124.css.gz +0 -0
- data/public/avo-packs/js/application-8071f9a0f167bb82b39d.js +0 -3
- data/public/avo-packs/js/application-8071f9a0f167bb82b39d.js.br +0 -0
- data/public/avo-packs/js/application-8071f9a0f167bb82b39d.js.gz +0 -0
- data/public/avo-packs/js/application-8071f9a0f167bb82b39d.js.map +0 -1
- data/public/avo-packs/js/application-8071f9a0f167bb82b39d.js.map.br +0 -0
- data/public/avo-packs/js/application-8071f9a0f167bb82b39d.js.map.gz +0 -0
@@ -1 +1 @@
|
|
1
|
-
<%= link_to Avo.configuration.app_name,
|
1
|
+
<%= link_to Avo.configuration.app_name, '/', class: 'text-green-600 font-semibold', target: :_blank %>
|
data/avo.gemspec
CHANGED
@@ -8,22 +8,36 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = 'avo'
|
9
9
|
spec.version = Avo::VERSION
|
10
10
|
spec.authors = ['Adrian Marin', 'Mihai Marin']
|
11
|
-
spec.email = ['
|
11
|
+
spec.email = ['avo@avohq.io']
|
12
12
|
spec.homepage = 'https://avohq.io'
|
13
|
-
spec.summary = 'Configuration
|
13
|
+
spec.summary = 'Configuration-based, no-maintenance, extendable Ruby on Rails admin.'
|
14
14
|
spec.description = 'Avo is a beautiful next-generation framework that empowers you, the developer, to create fantastic admin panels for your Ruby on Rails apps with the flexibility to fit your needs as you grow.'
|
15
|
-
spec.license = '
|
15
|
+
spec.license = 'Commercial'
|
16
16
|
|
17
17
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
18
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/avo-hq/avo/issues'
|
21
|
+
spec.metadata['changelog_uri'] = 'https://avohq.io/releases'
|
22
|
+
spec.metadata['documentation_uri'] = 'https://docs.avohq.io'
|
23
|
+
spec.metadata['homepage_uri'] = 'https://avohq.io'
|
24
|
+
spec.metadata['source_code_uri'] = 'https://github.com/avo-hq/avo'
|
25
|
+
else
|
26
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
27
|
+
'public gem pushes.'
|
28
|
+
end
|
29
|
+
|
30
|
+
spec.post_install_message = "Thank you for using Avo! Docs are available at https://docs.avohq.io"
|
19
31
|
|
20
32
|
spec.files = Dir['{bin,app,config,db,lib,public}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.md', 'avo.gemspec', 'Gemfile', 'Gemfile.lock']
|
21
33
|
.reject { |file| file.start_with? 'app/frontend' }
|
22
34
|
|
23
|
-
spec.add_dependency 'rails', '
|
35
|
+
spec.add_dependency 'rails', '>= 6.0'
|
24
36
|
spec.add_dependency 'kaminari'
|
25
37
|
spec.add_dependency 'zeitwerk'
|
26
38
|
spec.add_dependency 'inline_svg'
|
27
39
|
spec.add_dependency 'webpacker'
|
28
40
|
spec.add_dependency 'countries'
|
41
|
+
spec.add_dependency 'pundit'
|
42
|
+
spec.add_dependency 'httparty'
|
29
43
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
u5m9Je6F3j/LCnOwcN7cXW37M63Bs0KNZC1fHRObWx4YQkV9DJl1k9H9+mlvV3irAC7NZB9H0BExhxquReVe2N0v6s3E3EvOWY8wfZhFONJpK8V0qerYJIhJvCOOPv0hfS/HQdcvUQx/i1faXEgr8QVR7nGVBHUzulwgab0lUBSAV0jjEbT6o+amTojFudelgtw0zmlZW9JL7OZ/IwZ7zxbi8/yoWB52lU4VKOxZV7AEWAVDzL/0ZogLRG12BsTSmqC0jS5ocdnOgV0X7oNeYL9HINqLLM5suBB+BOf3xL6vgngu7UDRAAQ/mN2TDGsvklF8bwVz0dDVQ0RuvdeQ9TWEeM75hhzGKG6wPKBjh4ebrKp7g9TT76F6omLe/hG30MbohGxaLVHIJjyJixfKlLlYwdNWeOjXwYsn--7CEWrUIlraWa8R0S--ia1zVj/2AXISMmbinw6S7g==
|
data/config/routes.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
Avo::Engine.routes.draw do
|
2
2
|
root 'home#index'
|
3
3
|
|
4
|
-
get '/avo-api/
|
5
|
-
|
6
|
-
get '/avo-api/:resource_name', to: 'resources#index'
|
7
|
-
get '/avo-api/:resource_name/filters', to: 'resources#filters'
|
4
|
+
get '/avo-api/:resource_name/filters', to: 'filters#index'
|
5
|
+
|
8
6
|
get '/avo-api/:resource_name/actions', to: 'actions#index'
|
9
7
|
post '/avo-api/:resource_name/actions', to: 'actions#handle'
|
8
|
+
|
9
|
+
get '/avo-api/search', to: 'search#index'
|
10
|
+
get '/avo-api/:resource_name/search', to: 'search#resource'
|
11
|
+
|
12
|
+
get '/avo-api/:resource_name', to: 'resources#index'
|
10
13
|
post '/avo-api/:resource_name', to: 'resources#create'
|
11
|
-
get '/avo-api/:resource_name/
|
14
|
+
get '/avo-api/:resource_name/new', to: 'resources#new'
|
12
15
|
get '/avo-api/:resource_name/:id', to: 'resources#show'
|
13
16
|
get '/avo-api/:resource_name/:id/edit', to: 'resources#edit'
|
14
17
|
put '/avo-api/:resource_name/:id', to: 'resources#update'
|
15
18
|
delete '/avo-api/:resource_name/:id', to: 'resources#destroy'
|
16
|
-
|
17
|
-
post '/avo-api/:resource_name/:id/
|
19
|
+
|
20
|
+
post '/avo-api/:resource_name/:id/attach/:attachment_name/:attachment_id', to: 'relations#attach'
|
21
|
+
post '/avo-api/:resource_name/:id/detach/:attachment_name/:attachment_id', to: 'relations#detach'
|
18
22
|
|
19
23
|
# Tools
|
20
24
|
get '/avo-tools/resource-overview', to: 'resource_overview#index'
|
data/lib/avo.rb
CHANGED
data/lib/avo/app/app.rb
CHANGED
@@ -4,37 +4,35 @@ require_relative 'filters/select_filter'
|
|
4
4
|
require_relative 'filters/boolean_filter'
|
5
5
|
require_relative 'resource'
|
6
6
|
require_relative 'tool'
|
7
|
+
require_relative 'authorization_service'
|
7
8
|
|
8
9
|
module Avo
|
9
10
|
class App
|
10
11
|
@@app = {
|
11
12
|
root_path: '',
|
12
|
-
tools: [],
|
13
|
-
tool_classes: [],
|
14
13
|
resources: [],
|
15
14
|
field_names: {},
|
16
15
|
}
|
16
|
+
@@license = nil
|
17
17
|
|
18
18
|
class << self
|
19
|
-
def
|
19
|
+
def boot
|
20
20
|
@@app[:root_path] = Pathname.new(File.join(__dir__, '..', '..'))
|
21
|
-
# get_tools
|
22
|
-
# init_tools
|
23
21
|
init_fields
|
22
|
+
end
|
23
|
+
|
24
|
+
def init(current_request = nil)
|
24
25
|
init_resources
|
26
|
+
@@license = LicenseManager.new(HQ.new(current_request).response).license
|
25
27
|
end
|
26
28
|
|
27
29
|
def app
|
28
30
|
@@app
|
29
31
|
end
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# def get_tools
|
36
|
-
# @@app[:tool_classes] = ToolsManager.get_tools
|
37
|
-
# end
|
33
|
+
def license
|
34
|
+
@@license
|
35
|
+
end
|
38
36
|
|
39
37
|
# This method will take all fields available in the Avo::Fields namespace and create a method for them.
|
40
38
|
#
|
@@ -129,23 +127,14 @@ module Avo
|
|
129
127
|
name.to_s.camelize.singularize
|
130
128
|
end
|
131
129
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# @@app[:tools].each do |tool|
|
141
|
-
# navigation.push(tool.render_navigation) if tool.class.method_defined?(:render_navigation)
|
142
|
-
# end
|
143
|
-
|
144
|
-
# navigation.join('')
|
145
|
-
# end
|
146
|
-
|
147
|
-
def get_resources_navigation
|
148
|
-
App.get_resources.map { |resource| { label: resource.resource_name_plural.humanize, resource_name: resource.url.pluralize } }.to_json.to_s.html_safe
|
130
|
+
def get_resources_navigation(user)
|
131
|
+
App.get_resources
|
132
|
+
.select { |resource| AuthorizationService::authorize user, resource.model, Avo.configuration.authorization_methods.stringify_keys['index'] }
|
133
|
+
.map { |resource| { label: resource.resource_name_plural.humanize, resource_name: resource.url.pluralize } }
|
134
|
+
.reject { |i| i.blank? }
|
135
|
+
.to_json
|
136
|
+
.to_s
|
137
|
+
.html_safe
|
149
138
|
end
|
150
139
|
end
|
151
140
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Avo
|
2
|
+
class AuthorizationService
|
3
|
+
class << self
|
4
|
+
def authorize(user, record, action)
|
5
|
+
return true if skip_authorization
|
6
|
+
|
7
|
+
begin
|
8
|
+
if Pundit.policy user, record
|
9
|
+
Pundit.authorize user, record, action
|
10
|
+
end
|
11
|
+
true
|
12
|
+
rescue Pundit::NotAuthorizedError => error
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def authorize_action(user, record, action)
|
18
|
+
action = Avo.configuration.authorization_methods.stringify_keys[action.to_s]
|
19
|
+
|
20
|
+
return true if action.nil?
|
21
|
+
|
22
|
+
authorize user, record, action
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_policy(user, model)
|
26
|
+
return model if skip_authorization
|
27
|
+
|
28
|
+
begin
|
29
|
+
Pundit.policy_scope! user, model
|
30
|
+
rescue => exception
|
31
|
+
model
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def skip_authorization
|
36
|
+
Avo::App.license.lacks :authorization
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module Avo
|
2
2
|
module Fields
|
3
3
|
class IdField < Field
|
4
|
-
DEFAULT_VALUE = 'id'
|
5
|
-
|
6
4
|
def initialize(name, **args, &block)
|
5
|
+
default_value = 'id'
|
6
|
+
|
7
7
|
if name.nil?
|
8
|
-
@name = name =
|
8
|
+
@name = name = default_value
|
9
9
|
elsif !name.is_a? String and !name.is_a? Symbol
|
10
10
|
args_copy = name
|
11
|
-
@name = name =
|
11
|
+
@name = name = default_value
|
12
12
|
args = args_copy
|
13
13
|
end
|
14
14
|
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Avo
|
2
|
+
class HQ
|
3
|
+
attr_accessor :current_request
|
4
|
+
|
5
|
+
ENDPOINT = 'https://avohq.io/api/v1/licenses/check'
|
6
|
+
CACHE_KEY = 'avo.hq.response'
|
7
|
+
REQUEST_TIMEOUT = 5 # seconds
|
8
|
+
|
9
|
+
def initialize(current_request)
|
10
|
+
@current_request = current_request
|
11
|
+
end
|
12
|
+
|
13
|
+
def response
|
14
|
+
@hq_response or request
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def request
|
19
|
+
return cached_response if has_cached_response
|
20
|
+
|
21
|
+
begin
|
22
|
+
perform_and_cache_request
|
23
|
+
rescue HTTParty::Error => exception
|
24
|
+
cache_and_return_error 'HTTP client error.', exception.message
|
25
|
+
rescue Net::OpenTimeout => exception
|
26
|
+
cache_and_return_error 'Request timeout.', exception.message
|
27
|
+
rescue SocketError => exception
|
28
|
+
cache_and_return_error 'Connection error.', exception.message
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def perform_and_cache_request
|
33
|
+
hq_response = perform_request
|
34
|
+
|
35
|
+
return cache_and_return_error 'Avo HQ Internal server error.', hq_response.body if hq_response.code == 500
|
36
|
+
|
37
|
+
cache_response 1.hour.to_i, hq_response.parsed_response if hq_response.code == 200
|
38
|
+
end
|
39
|
+
|
40
|
+
def cache_response(time, response)
|
41
|
+
response.merge!(
|
42
|
+
expiry: time,
|
43
|
+
**payload,
|
44
|
+
).stringify_keys!
|
45
|
+
|
46
|
+
Rails.cache.write(CACHE_KEY, response, expires_in: time)
|
47
|
+
|
48
|
+
@hq_response = response
|
49
|
+
|
50
|
+
response
|
51
|
+
end
|
52
|
+
|
53
|
+
def perform_request
|
54
|
+
puts 'Performing request to avohq.io API to check license availability.'.inspect if Rails.env.development?
|
55
|
+
|
56
|
+
HTTParty.post ENDPOINT, body: payload.to_json, headers: { 'Content-type': 'application/json' }, timeout: REQUEST_TIMEOUT
|
57
|
+
end
|
58
|
+
|
59
|
+
def payload
|
60
|
+
{
|
61
|
+
license: Avo.configuration.license,
|
62
|
+
license_key: Avo.configuration.license_key,
|
63
|
+
avo_version: Avo::VERSION,
|
64
|
+
rails_version: Rails::VERSION::STRING,
|
65
|
+
ruby_version: RUBY_VERSION,
|
66
|
+
environment: Rails.env,
|
67
|
+
ip: current_request.ip,
|
68
|
+
host: current_request.host,
|
69
|
+
port: current_request.port,
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def cache_and_return_error(error, exception_message = '')
|
74
|
+
cache_response 5.minutes.to_i, { error: error, exception_message: exception_message }.stringify_keys
|
75
|
+
end
|
76
|
+
|
77
|
+
def has_cached_response
|
78
|
+
Rails.cache.exist? CACHE_KEY
|
79
|
+
end
|
80
|
+
|
81
|
+
def cached_response
|
82
|
+
Rails.cache.read CACHE_KEY
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Avo
|
2
|
+
class License
|
3
|
+
attr_accessor :id
|
4
|
+
attr_accessor :response
|
5
|
+
attr_accessor :valid
|
6
|
+
|
7
|
+
def initialize(response)
|
8
|
+
@response = response
|
9
|
+
@id = response['id']
|
10
|
+
@valid = response['valid']
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid?
|
14
|
+
valid
|
15
|
+
end
|
16
|
+
|
17
|
+
def invalid?
|
18
|
+
!valid?
|
19
|
+
end
|
20
|
+
|
21
|
+
def pro?
|
22
|
+
id == 'pro'
|
23
|
+
end
|
24
|
+
|
25
|
+
def error
|
26
|
+
@response['error']
|
27
|
+
end
|
28
|
+
|
29
|
+
def properties
|
30
|
+
@response.slice 'valid', 'id', 'error'
|
31
|
+
end
|
32
|
+
|
33
|
+
def abilities
|
34
|
+
[]
|
35
|
+
end
|
36
|
+
|
37
|
+
def can(ability)
|
38
|
+
abilities.include? ability
|
39
|
+
end
|
40
|
+
|
41
|
+
def cant(ability)
|
42
|
+
!can ability
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :has, :can
|
46
|
+
alias_method :lacks, :cant
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'license'
|
2
|
+
require_relative 'community_license'
|
3
|
+
require_relative 'pro_license'
|
4
|
+
require_relative 'null_license'
|
5
|
+
|
6
|
+
module Avo
|
7
|
+
class LicenseManager
|
8
|
+
def initialize(hq_response)
|
9
|
+
@hq_response = hq_response
|
10
|
+
end
|
11
|
+
|
12
|
+
def license
|
13
|
+
return NullLicense.new if Rails.env.test? and ENV['RUN_WITH_NULL_LICENSE'] == '1'
|
14
|
+
|
15
|
+
case @hq_response['id']
|
16
|
+
when 'community'
|
17
|
+
CommunityLicense.new @hq_response
|
18
|
+
when 'pro'
|
19
|
+
ProLicense.new @hq_response
|
20
|
+
else
|
21
|
+
NullLicense.new @hq_response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/avo/app/resource.rb
CHANGED
@@ -12,11 +12,12 @@ module Avo
|
|
12
12
|
attr_reader :default_view_type
|
13
13
|
|
14
14
|
class << self
|
15
|
-
def hydrate_resource(model
|
15
|
+
def hydrate_resource(model:, resource:, view: :index, user:)
|
16
16
|
default_panel_name = "#{resource.name} details"
|
17
17
|
|
18
18
|
resource_with_fields = {
|
19
19
|
id: model.id,
|
20
|
+
authorization: get_authorization(user, model),
|
20
21
|
resource_name_singular: resource.resource_name_singular,
|
21
22
|
resource_name_plural: resource.resource_name_plural,
|
22
23
|
title: model[resource.title],
|
@@ -39,6 +40,8 @@ module Avo
|
|
39
40
|
|
40
41
|
furnished_field = field.fetch_for_resource(model, resource, view)
|
41
42
|
|
43
|
+
next unless field_resource_authorized field, furnished_field, user
|
44
|
+
|
42
45
|
next if furnished_field.blank?
|
43
46
|
|
44
47
|
furnished_field[:panel_name] = default_panel_name
|
@@ -74,6 +77,22 @@ module Avo
|
|
74
77
|
|
75
78
|
"/resources/#{url}"
|
76
79
|
end
|
80
|
+
|
81
|
+
def get_authorization(user, model)
|
82
|
+
[:create, :update, :show, :destroy].map do |action|
|
83
|
+
[action, AuthorizationService::authorize_action(user, model, action)]
|
84
|
+
end.to_h
|
85
|
+
end
|
86
|
+
|
87
|
+
def field_resource_authorized(field, furnished_field, user)
|
88
|
+
if [Avo::Fields::HasManyField, Avo::Fields::HasAndBelongsToManyField].include? field.class
|
89
|
+
return true if furnished_field[:relationship_model].nil?
|
90
|
+
|
91
|
+
AuthorizationService.authorize user, furnished_field[:relationship_model].safe_constantize, Avo.configuration.authorization_methods.stringify_keys['index']
|
92
|
+
else
|
93
|
+
true
|
94
|
+
end
|
95
|
+
end
|
77
96
|
end
|
78
97
|
|
79
98
|
def name
|
@@ -138,26 +157,26 @@ module Avo
|
|
138
157
|
@search
|
139
158
|
end
|
140
159
|
|
141
|
-
def query_search(query: '', via_resource_name: , via_resource_id:)
|
142
|
-
|
160
|
+
def query_search(query: '', via_resource_name: , via_resource_id:, user:)
|
161
|
+
model_class = self.model
|
162
|
+
|
163
|
+
db_query = AuthorizationService.with_policy(user, model_class)
|
143
164
|
|
144
165
|
if via_resource_name.present?
|
145
|
-
|
146
|
-
|
166
|
+
related_model = App.get_resource_by_name(via_resource_name).model
|
167
|
+
|
147
168
|
db_query = related_model.find(via_resource_id).public_send(self.resource_name_plural.downcase)
|
148
169
|
end
|
149
170
|
|
171
|
+
new_query = []
|
172
|
+
|
150
173
|
[self.search].flatten.each_with_index do |search_by, index|
|
151
|
-
|
174
|
+
new_query.push 'or' if index != 0
|
152
175
|
|
153
|
-
|
154
|
-
db_query = db_query.where query_string
|
155
|
-
else
|
156
|
-
db_query = db_query.or(self.model.where query_string)
|
157
|
-
end
|
176
|
+
new_query.push "text(#{search_by}) ILIKE '%#{query}%'"
|
158
177
|
end
|
159
178
|
|
160
|
-
db_query.
|
179
|
+
db_query.where(new_query.join(' '))
|
161
180
|
end
|
162
181
|
|
163
182
|
def model
|