diff --git a/app/helpers/administrate/application_helper.rb b/app/helpers/administrate/application_helper.rb index c72368f0e8..0941b00337 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 e3eebf0a41..b5e66e823a 100644 --- a/lib/administrate/field/base.rb +++ b/lib/administrate/field/base.rb @@ -36,6 +36,19 @@ def self.permitted_attribute(attr, _options = nil) attr end + def self.partial_prefixes + @partial_prefixes ||= + if superclass.respond_to?(:partial_prefixes) + local_partial_prefixes + superclass.partial_prefixes + else + local_partial_prefixes + end + end + + def self.local_partial_prefixes + ["fields/#{field_type}"] + end + def initialize(attribute, data, page, options = {}) @attribute = attribute @page = page @@ -70,8 +83,8 @@ def read_value(data) end 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..9e0a57a5ff 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 409d85ee7f..d441e73575 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", "fields/base"]) end end diff --git a/spec/lib/fields/boolean_spec.rb b/spec/lib/fields/boolean_spec.rb index 1ad81ae1b7..8facd55e88 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", "fields/base"]) end end diff --git a/spec/lib/fields/email_spec.rb b/spec/lib/fields/email_spec.rb index 150001cb06..1056a5dd13 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", "fields/base"]) end end end diff --git a/spec/lib/fields/has_many_spec.rb b/spec/lib/fields/has_many_spec.rb index 8721c367c1..7db5a3692f 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", "fields/base"]) end end diff --git a/spec/lib/fields/has_one_spec.rb b/spec/lib/fields/has_one_spec.rb index 675eafa5ae..6bc5871105 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", "fields/base"]) end end diff --git a/spec/lib/fields/number_spec.rb b/spec/lib/fields/number_spec.rb index 03202038ad..ed86c944ef 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", "fields/base"]) end end diff --git a/spec/lib/fields/password_spec.rb b/spec/lib/fields/password_spec.rb index 06b7728427..25667cc597 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", "fields/base"]) end end diff --git a/spec/lib/fields/polymorphic_spec.rb b/spec/lib/fields/polymorphic_spec.rb index e08cffbdab..638a0e596e 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", "fields/base"] + ) end end diff --git a/spec/lib/fields/rich_text_spec.rb b/spec/lib/fields/rich_text_spec.rb index c2757ad86c..10e02048c1 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", "fields/base"]) end end diff --git a/spec/lib/fields/string_spec.rb b/spec/lib/fields/string_spec.rb index 3688aa1cfc..36fa92f4ee 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", "fields/base"]) end end diff --git a/spec/lib/fields/time_spec.rb b/spec/lib/fields/time_spec.rb index 6519e6b5f8..fc022358e7 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", "fields/base"]) end end diff --git a/spec/lib/fields/url_spec.rb b/spec/lib/fields/url_spec.rb index dc3e94b526..2bd33e5213 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", "fields/base"]) end end