Skip to content

Update client.Field.map_fields to produce more idomatic ruby method names from attributes #428

@jcouball

Description

@jcouball

The existing implementation will create method names that have capital letters or multiple underscores in a row. See an example in the code comments below.

Consider using the below implementation.

This would be a backward incompatible change for users who depend on the existing client.Field.map_fields behavior.

I wanted to make a note of my code here but didn't have time for a full PR with tests. Figured I'd make a note of it here and get feedback before investing in tests.

module JIRA
  # Extension to Jira resources
  module Resource
    # Extend the JIRA::Resource::Field class to map custom fields to a method name
    # using active support camelize
    class Field < JIRA::Base
      # Translate a custom field description to a underscore-case, method-safe name
      #
      # Enable this field translation by calling `client.Field.map_fields`.
      #
      # This enables use of this safe name in the following places:
      #
      # * As the method names for accessing the custom field value on the resource
      #
      #   ```ruby
      #   # For custom issue field whose id is 'customfield_13806' and whose
      #   # name is 'Target start'
      #   issue = client.Issue.find('PDT-123')
      #   issue.customfield_13806 #=> "2021-01-01"
      #   issue.target_start #=> "2021-01-01"
      #   ```
      #
      # * As names of fields to return from a JQL query
      #
      #   For custom issue field whose id is 'customfield_13806' and whose
      #   # name is 'Target start':
      #
      #   ```ruby
      #   query_string = 'project = PDT'
      #   client.Issue.jql(query_string, fields: %w[key target_start])
      #   ```
      #
      #   **Note** that field names in the query string must use the field name, not
      #   the method name.
      #
      #   ```ruby
      #   query_string = "project = PDT AND 'Target start' > '2021-01-01'"
      #
      #   # or
      #   target_start_field = client.Field.find('customfield_13806').name #=> "Target start"
      #   query_string = "project = PDT AND '#{target_start_field}' > '2021-01-01'"
      #
      #   client.Issue.jql(query_string, fields: %w[key target_start])
      #   ```
      #
      # * As a safe field name can NOT be used when creating an issue
      #
      #   ```ruby
      #   fields = {
      #     project: { key: 'PDT' },
      #     summary: 'Test issue',
      #     issuetype: { name: 'Epic' },
      #     customfield_13806: '2021-01-01',
      #     description: 'This is a test issue'
      #   }
      #   issue = client.Issue.build
      #   issue.save!({ fields: fields })
      #   ```
      #
      # * As a safe field name can NOT be used when updating an issue
      #
      #   ```ruby
      #   issue = client.Issue.find('PDT-1')
      #   issue.save!({ fields: { customfield_13806: '2025-06-01' } })
      #   ```
      #
      def self.safe_name(description)
        description.downcase.tap do |name|
          name.gsub!(/\s+|[^\w]+/, '_') # Replace spaces and non-word characters with underscores
          name.gsub!(/^_+|_+$/, '') # Remove leading and trailing underscores
          name.gsub!(/_+/, '_') # Replace multiple underscores with a single underscore
        end
      end
    end
  end
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    EnhancementEnhancements to existing features

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions