Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect enum fields as Selects rather than as Strings #1655

Merged
merged 3 commits into from
Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 } },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little thing, but I wonder if we can use the lamdba do; end syntax here to achieve the same goal?

Copy link
Contributor Author

@tadeusz-niemiec tadeusz-niemiec May 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It all depends on how good the parser will be, because I fetch raw file line there and parse it using regexp. We'll see how this idea works out and I'll try to implement parser for all possible syntaxes if it's the way to go.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [108/80]

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