ActiveHash

repository·master·Indexed 23 days ago

https://github.com/active-hash/active_hash

A Ruby library that provides a base class to use Ruby hashes as read-only, ActiveRecord-like data sources. It is designed for in-memory data, testing without databases, or managing static lookup data. It includes support for ActiveRecord associations, I18n, and data storage via ActiveYaml, ActiveJSON, and ActiveFile for custom formats like CSV or XML.

Tokens
6.6K
Snippets
17
Records
44
Agent score
78%

What's inside active-hash

  1. Configure ActiveYaml key attributes and hash style

    master

    When using the hash style in your YAML file, ActiveYaml automatically adds a key attribute based on the object's name in the hash. You can manually override this by specifying a key field within the YAML object.

    Methods for accessing keys:

    • Country.find(id).key
    • Country.find_by_key('key_name')
  2. Expose ActiveHash records as Enums

    master

    By including ActiveHash::Enum and using enum_accessor, you can turn your data records into Ruby constants. This allows you to access records via namespaced constants.

    • Single attribute: enum_accessor :name creates constants like Country::US.
    • Multiple attributes: enum_accessor :name, :state creates combined constants like Town::COLUMBUS_NY.

    Rules for constant names:

    • Non-word characters are stripped.
    • The result is upcased.
    • The field used for the accessor must contain unique values.
    class Country < ActiveHash::Base
      include ActiveHash::Enum
      self.data = [
          {:id => 1, :name => "US", :capital => "Washington, DC"},
          {:id => 2, :name => "Canada", :capital => "Ottawa"}
      ]
      enum_accessor :name
    end
    
    # Usage
    Country::US.capital # => "Washington DC"
  3. Associate ActiveRecord models with ActiveHash

    master

    You can use belongs_to_active_hash in an ActiveRecord model to create an association with an ActiveHash model.

    To enable this globally for all ActiveRecord models, extend ActiveRecord::Base with ActiveHash::Associations::ActiveRecordExtensions. Otherwise, extend the specific model.

    Example with shortcuts: By using the :shortcuts option, you can assign the association using a string (e.g., country_name) instead of an ID.

    class Person < ActiveRecord::Base
      extend ActiveHash::Associations::ActiveRecordExtensions
      belongs_to_active_hash :country, :shortcuts => [:name]
    end
    
    # Usage:
    person = Person.new
    person.country_name = "US" # Automatically finds the Country with name "US"
    class Person < ActiveRecord::Base
      extend ActiveHash::Associations::ActiveRecordExtensions
      belongs_to_active_hash :country, :shortcuts => [:name]
    end
  4. Use ERB in ActiveYaml files

    master

    ActiveYaml supports Embedded Ruby (ERB) using <% %> and <%= %> syntax within your YAML files. This allows you to dynamically set values (e.g., using environment variables or random numbers).

    To disable ERB processing globally, set ActiveYaml::Base.process_erb = false in an initializer.

    - id: 1
      email: <%= "user#{rand(100)}@email.com" %>
      password: <%= ENV['USER_PASSWORD'] %>
  5. Create an ActiveHash model

    master

    To create a model that uses a Ruby hash as a readonly datasource, inherit from ActiveHash::Base and define the self.data array. ActiveHash assumes every hash in the array has an :id key.

    Example:

    class Country < ActiveHash::Base
      self.data = [
        {:id => 1, :name => "US"},
        {:id => 2, :name => "Canada"}
      ]
    end
    class Country < ActiveHash::Base
      self.data = [
        {:id => 1, :name => "US"},
        {:id => 2, :name => "Canada"}
      ]
    end
  6. Use ActiveYaml to store data in YAML files

    master

    Inherit from ActiveYaml::Base to manage data stored in YAML files. By default, it looks for a file named [classname_lowercase].yml in the same directory as the class file.

    You can customize the storage location and filename using set_root_path and set_filename.

    class Country < ActiveYaml::Base
      set_root_path "/u/data"
      set_filename "sample"
    end
    # Looks for /u/data/sample.yml
  7. Use ActiveJSON to store data in JSON files

    master

    Inherit from ActiveJSON::Base to manage data stored in JSON files. Similar to ActiveYaml, it defaults to looking for [classname_lowercase].json in the same directory. Use set_root_path and set_filename to customize the path.

    class Country < ActiveJSON::Base
      set_root_path "/u/data"
      set_filename "sample"
    end
    # Looks for /u/data/sample.json
  8. Use multiple files and aliases in ActiveYaml

    master

    Multiple Files

    To split data across several files, use use_multiple_files and set_filenames (plural). Note that you must stick to either array style or hash style; you cannot mix them.

    YAML Aliases

    Include ActiveYaml::Aliases to support YAML anchors and aliases. You can use keys starting with / (e.g., /aliases:) to store anchor definitions safely without them being treated as data attributes.

    class Country < ActiveYaml::Base
      use_multiple_files
      set_filenames "europe", "america", "asia", "africa"
    end
    class Soda < ActiveYaml::Base
      include ActiveYaml::Aliases
    end
  9. Reload ActiveYaml, ActiveJSON, and ActiveFile data

    master

    To force a reload of data from disk during development, call Model.reload(true).

    In a Rails application, you can use a before_action to ensure models are reloaded on every request (though note this resets state every request):

    before_action do
      [Model1, Model2, Model3].each { |m| m.reload(true) }
    end
  10. Use dynamic finder methods

    master

    ActiveHash automatically generates dynamic finder methods based on the fields you define. These follow the pattern find_by_<field_name> or find_all_by_<field_name>.

    • find_by_<field>: Returns the first record matching the criteria.
    • find_all_by_<field>: Returns all records matching the criteria.
    • find_by_<field>!: Returns the first record matching the criteria or raises ActiveHash::RecordNotFound if no record is found.

    Example usage:

    class Country < ActiveHash::Base
      fields :name, :code
    end
    
    # Returns the first record where name is 'Canada'
    Country.find_by_name('Canada')
    
    # Returns all records where code is 'US'
    Country.find_all_by_code('US')
    
    # Raises ActiveHash::RecordNotFound if not found
    Country.find_by_name!('NonExistent')
  11. How `enum_accessor` generates constants

    master

    When you call enum_accessor(*field_names), ActiveHash::Enum tracks these fields to generate class constants for specific records.

    Constant Naming Logic:

    1. The values of the specified fields are joined with an underscore (_).
    2. Any non-word characters (\W+) are replaced with underscores.
    3. Leading and trailing underscores are stripped.
    4. The resulting string is converted to UPPERCASE.

    Example: If a record has country: 'United States' and status: 'active', and you have enum_accessor :country, :status, the constant name will be UNITED_STATES_ACTIVE.

    Error Handling: If you attempt to define a constant that is already defined by another record, it will raise a ActiveHash::Enum::DuplicateEnumAccessor error, unless the existing constant points to the exact same record.