Skip to content

Commit

Permalink
Detect enum fields as Selects rather than as Strings (#1655)
Browse files Browse the repository at this point in the history
* Fixes thoughtbot/administrate#1629

* Define enum collection option as a proc

* make proc regexp better

Co-authored-by: Tadeusz Niemiec <tadeusz@applover.pl>
  • Loading branch information
KingTiger001 and Tadeusz Niemiec committed Jun 2, 2020
1 parent 1a3a867 commit 39aff07
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 23 deletions.
8 changes: 5 additions & 3 deletions lib/administrate/field/select.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ def selectable_options
private

def collection
maybe_proc = options.fetch(:collection, [])
return maybe_proc.call if maybe_proc.respond_to? :call
values = options.fetch(:collection, [])
if values.respond_to? :call
return values.arity.positive? ? values.call(self) : values.call
end

@collection ||= maybe_proc
@collection ||= values
end
end
end
Expand Down
17 changes: 14 additions & 3 deletions lib/generators/administrate/dashboard/dashboard_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class DashboardGenerator < Rails::Generators::NamedBase
boolean: "Field::Boolean",
date: "Field::Date",
datetime: "Field::DateTime",
enum: "Field::String",
enum: "Field::Select",
float: "Field::Number",
integer: "Field::Number",
time: "Field::Time",
Expand All @@ -16,7 +16,9 @@ class DashboardGenerator < Rails::Generators::NamedBase
}

ATTRIBUTE_OPTIONS_MAPPING = {
enum: { searchable: false },
# procs must be defined in one line!
enum: { searchable: false,
collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys } },
float: { decimals: 2 },
}

Expand Down Expand Up @@ -136,7 +138,16 @@ def options_string(options)
end

def inspect_hash_as_ruby(hash)
hash.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
hash.map do |key, value|
v_str = value.respond_to?(:call) ? proc_string(value) : value.inspect
"#{key}: #{v_str}"
end.join(", ")
end

def proc_string(value)
source = value.source_location
proc_string = IO.readlines(source.first)[source.second - 1]
proc_string[/->[^}]*} | (lambda|proc).*end/x]
end
end
end
Expand Down
58 changes: 41 additions & 17 deletions spec/generators/dashboard_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,52 @@ class InventoryItem < ApplicationRecord
end
end

it "detects enum field as `String`" do
begin
ActiveRecord::Schema.define do
create_table :shipments do |t|
t.integer :status
end
it "detects enum field as `Select`" do
ActiveRecord::Schema.define do
create_table :shipments do |t|
t.integer :status
end
end

class Shipment < ApplicationRecord
enum status: [:ready, :processing, :shipped]
reset_column_information
end
class Shipment < ApplicationRecord
enum status: %i[ready processing shipped]
reset_column_information
end

run_generator ["shipment"]
load file("app/dashboards/shipment_dashboard.rb")
attrs = ShipmentDashboard::ATTRIBUTE_TYPES
run_generator ["shipment"]
load file("app/dashboards/shipment_dashboard.rb")
attrs = ShipmentDashboard::ATTRIBUTE_TYPES

expect(attrs[:status]).
to eq(Administrate::Field::String.with_options(searchable: false))
ensure
remove_constants :Shipment, :ShipmentDashboard
expect(attrs[:status].deferred_class).to eq(Administrate::Field::Select)
ensure
remove_constants :Shipment, :ShipmentDashboard
end

it "handles collection procs option in the 'Select' field" do
ActiveRecord::Schema.define do
create_table :shipments do |t|
t.integer :status
end
end

class Shipment < ApplicationRecord
enum status: %i[ready processing shipped]
reset_column_information
end

run_generator ["shipment"]
load file("app/dashboards/shipment_dashboard.rb")
attrs = ShipmentDashboard::ATTRIBUTE_TYPES
enum_collection_option = attrs[:status].options[:collection]
select_field = Administrate::Field::Select.new(:status,
nil,
attrs[:status].options,
resource: Shipment.new)

expect(enum_collection_option.call(select_field)).
to eq(Shipment.statuses.keys)
ensure
remove_constants :Shipment, :ShipmentDashboard
end

it "detects boolean values" do
Expand Down

0 comments on commit 39aff07

Please sign in to comment.