From c660ecdf29b8f640f9acf217ccd19e4e5a47e9c9 Mon Sep 17 00:00:00 2001 From: bobf Date: Tue, 20 Jun 2017 10:58:53 +0100 Subject: [PATCH] Allow custom scope for dashboard resource (#910) * Allow custom scope for dashboard resource * HoundCI fixes --- .../administrate/application_controller.rb | 5 ++- lib/administrate/resource_resolver.rb | 4 ++ lib/administrate/search.rb | 6 +-- .../administrate/resource_resolver_spec.rb | 32 +++++++++++++ spec/lib/administrate/search_spec.rb | 45 +++++++++++++++---- 5 files changed, 79 insertions(+), 13 deletions(-) diff --git a/app/controllers/administrate/application_controller.rb b/app/controllers/administrate/application_controller.rb index 2db8458ed9..6018e8a710 100644 --- a/app/controllers/administrate/application_controller.rb +++ b/app/controllers/administrate/application_controller.rb @@ -105,7 +105,7 @@ def requested_resource end def find_resource(param) - resource_class.find(param) + resource_scope.find(param) end def resource_includes @@ -117,7 +117,8 @@ def resource_params permit(dashboard.permitted_attributes) end - delegate :resource_class, :resource_name, :namespace, to: :resource_resolver + delegate :resource_class, :resource_name, :namespace, :resource_scope, + to: :resource_resolver helper_method :namespace helper_method :resource_name diff --git a/lib/administrate/resource_resolver.rb b/lib/administrate/resource_resolver.rb index 2a68ff0ec0..7f6a25e8c6 100644 --- a/lib/administrate/resource_resolver.rb +++ b/lib/administrate/resource_resolver.rb @@ -16,6 +16,10 @@ def resource_class Object.const_get(resource_class_name) end + def resource_scope + dashboard_class.new.try(:resource_scope) || resource_class.default_scoped + end + def resource_name model_path_parts.map(&:underscore).join("__").to_sym end diff --git a/lib/administrate/search.rb b/lib/administrate/search.rb index 936e2c3a24..8246246941 100644 --- a/lib/administrate/search.rb +++ b/lib/administrate/search.rb @@ -10,15 +10,15 @@ def initialize(resolver, term) def run if @term.blank? - resource_class.all + resource_scope.all else - resource_class.where(query, *search_terms) + resource_scope.where(query, *search_terms) end end private - delegate :resource_class, to: :resolver + delegate :resource_class, :resource_scope, to: :resolver def query search_attributes.map do |attr| diff --git a/spec/lib/administrate/resource_resolver_spec.rb b/spec/lib/administrate/resource_resolver_spec.rb index 5328132179..6458e7955c 100644 --- a/spec/lib/administrate/resource_resolver_spec.rb +++ b/spec/lib/administrate/resource_resolver_spec.rb @@ -60,6 +60,38 @@ module Library; class Book; end; end end end + describe "#resource_scope" do + it "defaults to model default scope when no override defined" do + begin + class Post + def self.default_scoped + "default scope" + end + end + class PostDashboard; end + resolver = Administrate::ResourceResolver.new("admin/posts") + expect(resolver.resource_scope).to eq("default scope") + ensure + remove_constants :PostDashboard, :Post + end + end + + it "uses defined scope when present" do + begin + class Post; end + class PostDashboard + def resource_scope + "a resource scope" + end + end + resolver = Administrate::ResourceResolver.new("admin/posts") + expect(resolver.resource_scope).to eq("a resource scope") + ensure + remove_constants :PostDashboard, :Post + end + end + end + describe "#resource_title" do it "handles global-namepsace models" do resolver = Administrate::ResourceResolver.new("admin/users") diff --git a/spec/lib/administrate/search_spec.rb b/spec/lib/administrate/search_spec.rb index 11f83244b9..a85807eabd 100644 --- a/spec/lib/administrate/search_spec.rb +++ b/spec/lib/administrate/search_spec.rb @@ -18,9 +18,11 @@ class MockDashboard it "returns all records when no search term" do begin class User; end - resolver = double(resource_class: User, dashboard_class: MockDashboard) + scope = double(all: nil) + resolver = double(resource_class: User, dashboard_class: MockDashboard, + resource_scope: scope) search = Administrate::Search.new(resolver, nil) - expect(User).to receive(:all) + expect(scope).to receive(:all) search.run ensure @@ -31,9 +33,11 @@ class User; end it "returns all records when search is empty" do begin class User; end - resolver = double(resource_class: User, dashboard_class: MockDashboard) + scope = double(all: nil) + resolver = double(resource_class: User, dashboard_class: MockDashboard, + resource_scope: scope) search = Administrate::Search.new(resolver, " ") - expect(User).to receive(:all) + expect(scope).to receive(:all) search.run ensure @@ -44,7 +48,9 @@ class User; end it "searches using lower() + LIKE for all searchable fields" do begin class User < ActiveRecord::Base; end - resolver = double(resource_class: User, dashboard_class: MockDashboard) + scope = double(where: nil) + resolver = double(resource_class: User, dashboard_class: MockDashboard, + resource_scope: scope) search = Administrate::Search.new(resolver, "test") expected_query = [ "lower(\"users\".\"name\") LIKE ?"\ @@ -52,7 +58,7 @@ class User < ActiveRecord::Base; end "%test%", "%test%", ] - expect(User).to receive(:where).with(*expected_query) + expect(scope).to receive(:where).with(*expected_query) search.run ensure @@ -63,7 +69,9 @@ class User < ActiveRecord::Base; end it "converts search term lower case for latin and cyrillic strings" do begin class User < ActiveRecord::Base; end - resolver = double(resource_class: User, dashboard_class: MockDashboard) + scope = double(where: nil) + resolver = double(resource_class: User, dashboard_class: MockDashboard, + resource_scope: scope) search = Administrate::Search.new(resolver, "Тест Test") expected_query = [ "lower(\"users\".\"name\") LIKE ?"\ @@ -71,12 +79,33 @@ class User < ActiveRecord::Base; end "%тест test%", "%тест test%", ] - expect(User).to receive(:where).with(*expected_query) + expect(scope).to receive(:where).with(*expected_query) search.run ensure remove_constants :User end end + + it "respects Dashboard#resource_scope when defined" do + begin + class MockScope + end + class User < ActiveRecord::Base + scope :my_scope, -> { MockScope } + end + class UserDashboard < Administrate::BaseDashboard + def resource_scope + User.my_scope + end + end + resolver = Administrate::ResourceResolver.new("admin/users") + search = Administrate::Search.new(resolver, nil) + expect(MockScope).to receive(:all) + search.run + ensure + remove_constants :User, :UserDashboard, :MockScope + end + end end end