From 5027f67d5187094394638ed69c82f929441b6638 Mon Sep 17 00:00:00 2001 From: nakamura Date: Fri, 4 Oct 2024 16:30:04 +0000 Subject: [PATCH] Introduce partial search similar to Rails --- .../administrate/application_helper.rb | 10 +++++++- lib/administrate/field/base.rb | 17 ++++++++++++-- .../views/fields/has_one/_show_spec.rb | 9 +++++--- .../fields/has_many_variant/_form.html.erb | 13 ----------- .../fields/has_many_variant/_index.html.erb | 6 ----- .../fields/has_many_variant/_show.html.erb | 23 ------------------- .../administrate/application_helper_spec.rb | 18 +++++++++++++++ spec/lib/fields/belongs_to_spec.rb | 6 ++--- spec/lib/fields/boolean_spec.rb | 6 ++--- spec/lib/fields/email_spec.rb | 6 ++--- spec/lib/fields/has_many_spec.rb | 6 ++--- spec/lib/fields/has_one_spec.rb | 6 ++--- spec/lib/fields/number_spec.rb | 6 ++--- spec/lib/fields/password_spec.rb | 6 ++--- spec/lib/fields/polymorphic_spec.rb | 8 ++++--- spec/lib/fields/rich_text_spec.rb | 6 ++--- spec/lib/fields/string_spec.rb | 6 ++--- spec/lib/fields/time_spec.rb | 6 ++--- spec/lib/fields/url_spec.rb | 6 ++--- 19 files changed, 86 insertions(+), 84 deletions(-) delete mode 100644 spec/example_app/app/views/fields/has_many_variant/_form.html.erb delete mode 100644 spec/example_app/app/views/fields/has_many_variant/_index.html.erb delete mode 100644 spec/example_app/app/views/fields/has_many_variant/_show.html.erb diff --git a/app/helpers/administrate/application_helper.rb b/app/helpers/administrate/application_helper.rb index c72368f0e8..5490303b4b 100644 --- a/app/helpers/administrate/application_helper.rb +++ b/app/helpers/administrate/application_helper.rb @@ -9,7 +9,15 @@ def application_title def render_field(field, locals = {}) locals[:field] = field - render locals: locals, partial: field.to_partial_path + if (prefix = find_partial_prefix(field)) + render locals: locals, partial: "#{prefix}/#{field.page}" + end + end + + def find_partial_prefix(field) + field._partial_prefixes.detect do |prefix| + lookup_context.template_exists?(field.page, [prefix], true) + end end def requireness(field) diff --git a/lib/administrate/field/base.rb b/lib/administrate/field/base.rb index c086603afb..9a5bb93574 100644 --- a/lib/administrate/field/base.rb +++ b/lib/administrate/field/base.rb @@ -32,6 +32,19 @@ def self.permitted_attribute(attr, _options = nil) attr end + def self._partial_prefixes + @_partial_prefixes ||= begin + return local_partial_prefixes if superclass == Administrate::Field::Base + + local_partial_prefixes + superclass._partial_prefixes + end + end + + def self.local_partial_prefixes + ["fields/#{field_type}"] + end + private_class_method :local_partial_prefixes + def initialize(attribute, data, page, options = {}) @attribute = attribute @data = data @@ -52,8 +65,8 @@ def name attribute.to_s end - def to_partial_path - "/fields/#{self.class.field_type}/#{page}" + def _partial_prefixes + self.class._partial_prefixes end def required? diff --git a/spec/administrate/views/fields/has_one/_show_spec.rb b/spec/administrate/views/fields/has_one/_show_spec.rb index 5bc71c57b7..e878b1d29c 100644 --- a/spec/administrate/views/fields/has_one/_show_spec.rb +++ b/spec/administrate/views/fields/has_one/_show_spec.rb @@ -35,7 +35,8 @@ name: "simple_string_field", truncate: "string value", html_class: "string", - to_partial_path: "fields/string/index" + page: "index", + _partial_prefixes: ["fields/string"] ) nested_show_page_for_has_one = instance_double( @@ -123,7 +124,8 @@ def render_field data: nested_collection, html_class: "has-many", name: "payments", - to_partial_path: "fields/has_many/index" + page: "index", + _partial_prefixes: ["fields/has_many"] ) nested_show_page_for_nested_has_one = instance_double( @@ -141,7 +143,8 @@ def render_field linkable?: true, nested_show: nested_show_page_for_nested_has_one, html_class: "has-one", - to_partial_path: "fields/has_one/show", + page: "show", + _partial_prefixes: ["fields/has_one"], display_associated_resource: "Resource Doubly Nested with HasOne", name: "page" ) diff --git a/spec/example_app/app/views/fields/has_many_variant/_form.html.erb b/spec/example_app/app/views/fields/has_many_variant/_form.html.erb deleted file mode 100644 index d977aae80c..0000000000 --- a/spec/example_app/app/views/fields/has_many_variant/_form.html.erb +++ /dev/null @@ -1,13 +0,0 @@ -<%# -Just a copy of the HasMany _form partial, here to test that -things won't break if the app adds new types of association fields -%> - -
- <%= f.label field.attribute_key, field.attribute %> -
-
- <%= f.select(field.attribute_key, nil, {}, multiple: true) do %> - <%= options_for_select(field.associated_resource_options, field.selected_options) %> - <% end %> -
diff --git a/spec/example_app/app/views/fields/has_many_variant/_index.html.erb b/spec/example_app/app/views/fields/has_many_variant/_index.html.erb deleted file mode 100644 index e131531a88..0000000000 --- a/spec/example_app/app/views/fields/has_many_variant/_index.html.erb +++ /dev/null @@ -1,6 +0,0 @@ -<%# -Just a copy of the HasMany _index partial, here to test that -things won't break if the app adds new types of association fields -%> - -<%= pluralize(field.data.size, field.attribute.to_s.humanize.downcase.singularize) %> diff --git a/spec/example_app/app/views/fields/has_many_variant/_show.html.erb b/spec/example_app/app/views/fields/has_many_variant/_show.html.erb deleted file mode 100644 index 1916db768d..0000000000 --- a/spec/example_app/app/views/fields/has_many_variant/_show.html.erb +++ /dev/null @@ -1,23 +0,0 @@ -<%# -Just a copy of the HasMany _show partial, here to test that -things won't break if the app adds new types of association fields -%> - -<% if field.resources.any? %> - <% order = field.order_from_params(params.fetch(field.name, {})) %> - <% page_number = params.fetch(field.name, {}).fetch(:page, nil) %> - <%= render( - "collection", - collection_presenter: field.associated_collection(order), - collection_field_name: field.name, - page: page, - resources: field.resources(page_number, order), - table_title: field.name, - ) %> - <% if field.more_than_limit? %> - <%= paginate field.resources(page_number), param_name: "#{field.name}[page]" %> - <% end %> - -<% else %> - <%= t("administrate.fields.has_many.none", default: "–") %> -<% end %> diff --git a/spec/helpers/administrate/application_helper_spec.rb b/spec/helpers/administrate/application_helper_spec.rb index da782c2185..4434251e70 100644 --- a/spec/helpers/administrate/application_helper_spec.rb +++ b/spec/helpers/administrate/application_helper_spec.rb @@ -1,6 +1,24 @@ require "rails_helper" +require "administrate/field/has_many" +require "administrate/field/has_many_variant" RSpec.describe Administrate::ApplicationHelper do + describe "#find_partial_prefix" do + context "when the field has a partial" do + it "returns the prefix" do + field = Administrate::Field::HasMany.new(:name, "hello", :show) + expect(find_partial_prefix(field)).to eq("fields/has_many") + end + end + + context "when the field does not have a partial and the superclass does" do + it "returns the superclass prefix" do + field = Administrate::Field::HasManyVariant.new(:name, "hello", :show) + expect(find_partial_prefix(field)).to eq("fields/has_many") + end + end + end + describe "#display_resource_name" do it "defaults to the plural of the model name" do displayed = display_resource_name(:customer) diff --git a/spec/lib/fields/belongs_to_spec.rb b/spec/lib/fields/belongs_to_spec.rb index 4ae0b1b8d9..541e186614 100644 --- a/spec/lib/fields/belongs_to_spec.rb +++ b/spec/lib/fields/belongs_to_spec.rb @@ -26,15 +26,15 @@ end end - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show owner = double field = Administrate::Field::BelongsTo.new(:owner, owner, page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/belongs_to/#{page}") + expect(prefixes).to eq(["fields/belongs_to", "fields/associative"]) end end diff --git a/spec/lib/fields/boolean_spec.rb b/spec/lib/fields/boolean_spec.rb index 1ad81ae1b7..b36aa70255 100644 --- a/spec/lib/fields/boolean_spec.rb +++ b/spec/lib/fields/boolean_spec.rb @@ -5,15 +5,15 @@ describe Administrate::Field::Boolean do include FieldMatchers - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show boolean = double field = Administrate::Field::Boolean.new(:price, boolean, page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/boolean/#{page}") + expect(prefixes).to eq(["fields/boolean"]) end end diff --git a/spec/lib/fields/email_spec.rb b/spec/lib/fields/email_spec.rb index 150001cb06..7e27aac66d 100644 --- a/spec/lib/fields/email_spec.rb +++ b/spec/lib/fields/email_spec.rb @@ -1,14 +1,14 @@ require "administrate/field/email" describe Administrate::Field::Email do - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show field = Administrate::Field::Email.new(:email, "foo@example.com", page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/email/#{page}") + expect(prefixes).to eq(["fields/email"]) end end end diff --git a/spec/lib/fields/has_many_spec.rb b/spec/lib/fields/has_many_spec.rb index 0d0bbd6904..78e869bd66 100644 --- a/spec/lib/fields/has_many_spec.rb +++ b/spec/lib/fields/has_many_spec.rb @@ -16,15 +16,15 @@ end end - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show items = double field = Administrate::Field::HasMany.new(:items, items, page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/has_many/#{page}") + expect(prefixes).to eq(["fields/has_many", "fields/associative"]) end end diff --git a/spec/lib/fields/has_one_spec.rb b/spec/lib/fields/has_one_spec.rb index 675eafa5ae..dbb0ec6ee9 100644 --- a/spec/lib/fields/has_one_spec.rb +++ b/spec/lib/fields/has_one_spec.rb @@ -77,7 +77,7 @@ end end - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do resource = double page = :show @@ -89,9 +89,9 @@ resource: resource ) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/has_one/#{page}") + expect(prefixes).to eq(["fields/has_one", "fields/associative"]) end end diff --git a/spec/lib/fields/number_spec.rb b/spec/lib/fields/number_spec.rb index 03202038ad..bd39bcea77 100644 --- a/spec/lib/fields/number_spec.rb +++ b/spec/lib/fields/number_spec.rb @@ -5,15 +5,15 @@ describe Administrate::Field::Number do include FieldMatchers - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show number = double field = Administrate::Field::Number.new(:price, number, page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/number/#{page}") + expect(prefixes).to eq(["fields/number"]) end end diff --git a/spec/lib/fields/password_spec.rb b/spec/lib/fields/password_spec.rb index 06b7728427..8865010781 100644 --- a/spec/lib/fields/password_spec.rb +++ b/spec/lib/fields/password_spec.rb @@ -5,14 +5,14 @@ describe Administrate::Field::Password do include FieldMatchers - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show field = Administrate::Field::Password.new(:password, "my_password", page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/password/#{page}") + expect(prefixes).to eq(["fields/password"]) end end diff --git a/spec/lib/fields/polymorphic_spec.rb b/spec/lib/fields/polymorphic_spec.rb index e08cffbdab..9727f04054 100644 --- a/spec/lib/fields/polymorphic_spec.rb +++ b/spec/lib/fields/polymorphic_spec.rb @@ -18,14 +18,16 @@ end end - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show field = Administrate::Field::Polymorphic.new(:foo, "hello", page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/polymorphic/#{page}") + expect(prefixes).to eq( + ["fields/polymorphic", "fields/belongs_to", "fields/associative"] + ) end end diff --git a/spec/lib/fields/rich_text_spec.rb b/spec/lib/fields/rich_text_spec.rb index c2757ad86c..d8dc8116a6 100644 --- a/spec/lib/fields/rich_text_spec.rb +++ b/spec/lib/fields/rich_text_spec.rb @@ -13,7 +13,7 @@ ) end - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show action_text = ActionText::RichText.new( @@ -21,9 +21,9 @@ ) field = Administrate::Field::RichText.new(:document, action_text, page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/rich_text/#{page}") + expect(prefixes).to eq(["fields/rich_text"]) end end diff --git a/spec/lib/fields/string_spec.rb b/spec/lib/fields/string_spec.rb index 3688aa1cfc..5e4c73a6df 100644 --- a/spec/lib/fields/string_spec.rb +++ b/spec/lib/fields/string_spec.rb @@ -5,14 +5,14 @@ describe Administrate::Field::String do include FieldMatchers - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show field = Administrate::Field::String.new(:string, "hello", page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/string/#{page}") + expect(prefixes).to eq(["fields/string"]) end end diff --git a/spec/lib/fields/time_spec.rb b/spec/lib/fields/time_spec.rb index bce4994696..e908a17e44 100644 --- a/spec/lib/fields/time_spec.rb +++ b/spec/lib/fields/time_spec.rb @@ -2,15 +2,15 @@ require "administrate/field/time" describe Administrate::Field::Time do - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show time = Time.zone.local(2000, 1, 1, 15, 45, 33) field = Administrate::Field::Time.new(:time, time, page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/time/#{page}") + expect(prefixes).to eq(["fields/time"]) end end diff --git a/spec/lib/fields/url_spec.rb b/spec/lib/fields/url_spec.rb index dc3e94b526..003fff9c1a 100644 --- a/spec/lib/fields/url_spec.rb +++ b/spec/lib/fields/url_spec.rb @@ -7,14 +7,14 @@ end end - describe "#to_partial_path" do + describe "#_partial_prefixes" do it "returns a partial based on the page being rendered" do page = :show field = Administrate::Field::Url.new(:url, "https://thoughtbot.com", page) - path = field.to_partial_path + prefixes = field._partial_prefixes - expect(path).to eq("/fields/url/#{page}") + expect(prefixes).to eq(["fields/url"]) end end