Ruby Best Practice - Динамические атрибуты против хэша для приложения RoR - PullRequest
0 голосов
/ 09 марта 2012

Я разрабатываю модель, которая содержит параметры конфигурации для параметров сервера.Количество и тип серверных опций меняются, и мне нужны сведения о плюсах и минусах двух способов сделать это.Я делаю это отдельно от базы данных рельсов ActiveRecord.Все мои взаимодействия с базой данных будут происходить вручную с файловой системой.

Во-первых, модель должна динамически создавать атрибуты, необходимые для каждого указанного сервера.(до тех пор, пока это возможно ... я никогда не делал этого раньше)

Во-вторых, создание одного хэша, который имеет ключи параметров сервера и значения параметров сервера.

Я думаю, что второе было бы легче реализовать, но я не уверен, что это правильный путь?Кажется, что лучше работать с динамическими атрибутами.

Есть ли эмпирическое правило для этого?

Ответы [ 2 ]

4 голосов
/ 09 марта 2012

Знаете ли вы о функциональности магазина в Rails?

http://api.rubyonrails.org/classes/ActiveRecord/Store.html

В принципе, вы могли бы написать что-то вроде этого:

class Server < ActiveRecord::Base
  store :options
end

Вам также необходимо создать новую миграцию со столбцом параметров и ввести текст.

Теперь вы можете добавлять и считывать значения в хранилище параметров следующим образом:

server_instance.options[:ip] = '10.0.1.7'
server_instance.options[:ip] # returns the IP.

Вы также можете убрать это, добавив опцию доступа к вызову магазина.

class Server < ActiveRecord::Base
  store :options, accessors: [ :ip, :port ]
end

Теперь вы можете использовать ip & port как обычные атрибуты.

server_instance.ip = '10.0.1.7'
server_instance.ip # returns the IP.
1 голос
/ 14 марта 2012

Сделал что-то для тебя.

Вот как это будет работать.

s = Settings.new(SettingsFileManager.new(some_file))

s.ip # returns whats in the file.
s.ip = 10.0.0.1 # overrides the new value.

Я еще не написал, как он взаимодействует с файлами, поэтому вам придется написать надлежащий SettingsFileManager.

Во всяком случае, это должно дать вам хорошую основу для начала.Но я написал это в первую очередь для проверки того, что я знаю о рубине.Так как он использует некоторые полусложные вещи.

Хостинг на github тоже с некоторыми тестами.

class Settings

  attr_accessor :settings

  def initialize(file_writer)
    @file_writer = file_writer
    read_settings_to_new_hash
  end

  def read_settings_to_new_hash
    @settings = fabricate_hash
    @settings.replace(@file_writer.read_keys)
  end

  def fabricate_hash
    InterceptedHash.new( &hash_saved_proc )
  end

  def hash_saved_proc
    Proc.new do |key, value|
      @file_writer.write_key(key, value)
    end
  end

  def method_missing(m, *args, &block)
    if @settings.has_key?(m) || args[0]
      if args[0]
        @settings[m.to_s.sub("=","").to_sym] = args[0]
      else
        @settings[m]
      end
    else
      raise "unknown setting"
    end
  end

end

# Not implemented. This should continue the logic to interact with whatever you want.
class SettingsFileManager
  def initialize(file)
    @file = file
  end

  # write the key and its value somewhere.
  def write_key(key, value)
    puts 'write_key', key, value
  end

  # should return hash of keys.
  def read_keys
    puts 'read_keys'
    Hash.new
  end
end

class InterceptedHash < Hash
  def initialize(&block)
    super
    @block = block
  end

  def store(key, value)
    super(key, value)
    @block.call(key, value)
  end

  def []=(key, value)
    store(key, value)
  end
end
...