Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to configure settings on an AR model

Intro

I have a Ruby model that needs to have a configuration option passed to it i.e. config/initializers/contact_import.rb define options so that:

ContactImport.import_mapping # => {'csv' => ..., 'csv_row' => ..., etc}

Option 1

Works in production environment, but not in development since classes reload

# config/initializers/contact_import.rb
ContactImport.import_mapping = {
  "csv" => CsvImport,
  "csv_row" => CsvImport,
  "mailchimp" => McImport,
  "vcard" => VcardImport
}

# app/models/contact_import.rb
class ContactImport < ActiveRecord::Base
  class << self
    attr_accessor :import_mapping
  end
end

Option 2

Works, but sets the value of the IMPORT_MAPPING twice, which creates a warning

# config/initializers/contact_import.rb
ContactImport.IMPORT_MAPPING = {
  "csv" => CsvImport,
  "csv_row" => CsvImport,
  "mailchimp" => McImport,
  "vcard" => VcardImport
}

# app/models/contact_import.rb
class ContactImport < ActiveRecord::Base
  IMPORT_MAPPING = {}

  def import_mapping
    IMPORT_MAPPING
  end
end

Option 3

More robust option initialization, but complains that I am calling the private method configure on a AR object. Also, creates an extra file to do the configuration parsing

# config/initializers/contact_import.rb
ContactImport.configure do |config|
  config.import_mapping = {
    "csv" => CsvImport,
    "csv_row" => CsvImport,
    "mailchimp" => McImport,
    "vcard" => VcardImport
  }
end

# app/models/contact_import.rb
class ContactImport << ActiveRecord::Base
  include ContactImportConfiguration
  ...
end

# lib/contact_import_configuration.rb
module ContactImportConfiguration
  class << self
    attr_accessor :configuration
  end

  def self.configure
    self.configuration ||= Configuration.new
    yield(configuration)
  end

  class Configuration
    attr_accessor :import_mapping

    def initialize
      @import_mapping = {}
    end
  end
end

Option 4

This is the one I chose

# config/initializers/contact_import_mapping.rb
module ContactImportMapping
  def import_mapping
    {
      "csv" => CsvImport,
      "csv_row" => CsvImport,
      "mailchimp" => McImport,
      "vcard" => VcardImport
    }
  end
end

# app/models/contact_import.rb
class ContactImport << ActiveRecord::Base
  extend ContactImportMapping
  ...
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.