diff --git a/app/views/fields/belongs_to/_form.html.erb b/app/views/fields/belongs_to/_form.html.erb
index 3021506ee0..5e8b62ca3f 100644
--- a/app/views/fields/belongs_to/_form.html.erb
+++ b/app/views/fields/belongs_to/_form.html.erb
@@ -20,7 +20,7 @@ that displays all possible records to associate with.
<%= f.label field.permitted_attribute %>
- <%= f.select(field.permitted_attribute) do %>
- <%= options_for_select(field.associated_resource_options, field.selected_option) %>
- <% end %>
+ <%= f.select(field.permitted_attribute,
+ options_for_select(field.associated_resource_options, field.selected_option),
+ include_blank: field.include_blank_option) %>
diff --git a/docs/customizing_dashboards.md b/docs/customizing_dashboards.md
index c5e76d998e..f6bd71ce0d 100644
--- a/docs/customizing_dashboards.md
+++ b/docs/customizing_dashboards.md
@@ -90,6 +90,9 @@ Example: `.with_options(scope: -> { MyModel.includes(:rel).limit(5) })`
`:class_name` - Specifies the name of the associated class.
Defaults to `:#{attribute}.to_s.singularize.camelcase`.
+`:include_blank` - Specifies if the select element to be rendered should include
+blank option. Default is `true`.
+
`:searchable` - Specify if the attribute should be considered when searching.
Default is `false`.
diff --git a/lib/administrate/field/belongs_to.rb b/lib/administrate/field/belongs_to.rb
index 8e788d8a3b..6b1b096a61 100644
--- a/lib/administrate/field/belongs_to.rb
+++ b/lib/administrate/field/belongs_to.rb
@@ -12,7 +12,7 @@ def permitted_attribute
end
def associated_resource_options
- [nil] + candidate_resources.map do |resource|
+ candidate_resources.map do |resource|
[display_candidate_resource(resource), resource.send(primary_key)]
end
end
@@ -21,6 +21,10 @@ def selected_option
data && data.send(primary_key)
end
+ def include_blank_option
+ options.fetch(:include_blank, true)
+ end
+
private
def candidate_resources
diff --git a/spec/example_app/app/dashboards/customer_dashboard.rb b/spec/example_app/app/dashboards/customer_dashboard.rb
index 4d719362de..eff8bc3881 100644
--- a/spec/example_app/app/dashboards/customer_dashboard.rb
+++ b/spec/example_app/app/dashboards/customer_dashboard.rb
@@ -18,6 +18,7 @@ class CustomerDashboard < Administrate::BaseDashboard
class_name: "Country",
searchable: true,
searchable_fields: ["name"],
+ include_blank: true,
),
password: Field::Password,
}
diff --git a/spec/features/form_spec.rb b/spec/features/form_spec.rb
index 414d322c0e..4ea58ad681 100644
--- a/spec/features/form_spec.rb
+++ b/spec/features/form_spec.rb
@@ -28,4 +28,38 @@
expect(page).to have_label(custom_label)
end
end
+
+ context "include_blank option for belongs_to" do
+ before { create_list(:country, 5) }
+
+ it "should have blank option if set to true" do
+ dashboard = CustomerDashboard.new
+ fields = dashboard.attribute_types
+ territory = fields[:territory]
+ territory.options[:include_blank] = true
+
+ expect(territory.deferred_class).to eq(Administrate::Field::BelongsTo)
+ expect(territory.options[:include_blank]).to eq(true)
+
+ visit new_admin_customer_path
+ element_selections = find("select[name=\"customer[country_code]\"]")
+
+ expect(element_selections.first("option").value).to eq("")
+ end
+
+ it "should not have blank option if set to false" do
+ dashboard = CustomerDashboard.new
+ fields = dashboard.attribute_types
+ territory = fields[:territory]
+ territory.options[:include_blank] = false
+
+ expect(territory.deferred_class).to eq(Administrate::Field::BelongsTo)
+ expect(territory.options[:include_blank]).to eq(false)
+
+ visit new_admin_customer_path
+ element_selections = find("select[name=\"customer[country_code]\"]")
+
+ expect(element_selections.first("option").value).not_to eq("")
+ end
+ end
end
diff --git a/spec/lib/fields/belongs_to_spec.rb b/spec/lib/fields/belongs_to_spec.rb
index af62904f5f..453e0aaec1 100644
--- a/spec/lib/fields/belongs_to_spec.rb
+++ b/spec/lib/fields/belongs_to_spec.rb
@@ -33,13 +33,39 @@
candidates = field.associated_resource_options
expect(Foo).to have_received(:all)
- expect(candidates).to eq([nil])
+ expect(candidates).to eq([])
ensure
remove_constants :Foo
end
end
end
+ describe "include_blank option" do
+ context "default value as true" do
+ it "determines if choices has blank option or not" do
+ association = Administrate::Field::BelongsTo
+ field = association.new(:customers, [], :edit)
+ candidates = field.associated_resource_options
+
+ expect(field.include_blank_option). to eq(true)
+ expect(candidates).to eq([])
+ end
+ end
+
+ context "set value as false" do
+ it "determines if choices has blank option or not" do
+ association = Administrate::Field::BelongsTo.with_options(
+ include_blank: false,
+ )
+ field = association.new(:customers, [], :edit)
+ candidates = field.associated_resource_options
+
+ expect(field.include_blank_option). to eq(false)
+ expect(candidates).to eq([])
+ end
+ end
+ end
+
describe "primary_key option" do
it "determines what primary key is used on the relationship for the form" do
begin