Skip to content

Instantly share code, notes, and snippets.

@bsimpson
Created June 29, 2012 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bsimpson/3019629 to your computer and use it in GitHub Desktop.
Save bsimpson/3019629 to your computer and use it in GitHub Desktop.
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