Загрузка файла YML в Rails и, возможно, использование файла i18n вместо - PullRequest
1 голос
/ 20 марта 2019

У меня есть файл dropdown.yml, в котором хранятся все мои раскрывающиеся значения для полей с несколькими вариантами выбора в моих формах. Это не зависит от окружающей среды, поэтому у меня нет: разработка, производство и т. Д.

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

config = Rails.application.config_for(:payment)

Однако похоже, что это зависит от окружающей среды. Каков наилучший способ добавить yml?

Во-вторых, я должен использовать локали для этого вместо пользовательского файла yml?

конфиг / dropdown.yml

dropdown:
  car_model:
    field1:
      yes: true
       no: false
    region:
      US: United States
      CA: Canada

Кроме того, есть ли способ сделать выпадающий список доступным для нескольких имен?

dropdown:
  car_model| truck_model| bike_model:
    field1:
      yes: true
       no: false
    region:
      US: United States
      CA: Canada

Чтобы я мог ссылаться на field1 с любого из именных ключей, car_model, truck_model или bike_model?

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Я думаю, я бы сделал для этого служебный класс и модуль.Что-то вроде:

module DropdownExt

  def self.extended(receiver)
    receiver.each do |k,v|
      define_method(k) do 
        v.is_a?(Hash) ? v.extend(DropdownExt) : v
      end
    end
  end

end

class Dropdowns

  class << self

    private

    def dropdowns_spec
      YAML.load_file("#{path}").with_indifferent_access
    end

    def path
      Rails.root.join("spec/so/dropdowns/dropdowns.yaml") # <== you'll need to change this
    end

  end

  dropdowns_spec[:dropdown].each do |k,v|
    define_singleton_method k do 
      v.extend(DropdownExt)
    end
  end

  %i(
    truck_model
    bike_model
  ).each do |to_alias|
    singleton_class.send(:alias_method, to_alias, :car_model)
  end

end

Тогда вы можете сделать:

Dropdowns.car_model
 => {"field1"=>{true=>"true", false=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
Dropdowns.truck_model
 => {"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
Dropdowns.bike_model
 => {"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}

Где угодно.

Вы заметите, что я расширил хеш модели с помощью пользовательского DropdownExt, так что вы также можете сделать:

Dropdowns.car_model.field1
 => {"yes"=>"true", "no"=>"false"}
Dropdowns.car_model.field1.yes 
 => "true"
Dropdowns.car_model.region.US
 => United States

Когда вы делаете extend(SomeModule) для экземпляра, тогда только этот экземпляр расширяется с помощью модуля, поэтому вы не получаете polute Hash (в данном случае)во всем приложении.

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

Еще одним преимуществом этого подхода является то, что вы получаете методы класса для каждой из ваших моделей «бесплатно».Поэтому вы можете сделать:

Dropdowns.car_model

вместо

Rails.application.config.dropdown[:car_model]

Я не знаю.Это только кажется мне лучше.

Наконец, я думаю, мне нравится инкапсулировать все это в классе.Опять же, вопрос личных предпочтений.Но это кажется мне более рубиновым.

Кстати, мой YAML хотел изменить ваши yes и no на true и false.Итак, я сделал:

---
dropdown:
  car_model:
    field1:
      'yes':  'true'
      'no':   'false'
    region:
      US: United States
      CA: Canada

Который вернул

{"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
1 голос
/ 20 марта 2019

Загрузите его в ваш application.rb внутри блока конфигурации:

class Application < Rails::Application
  ...
  config.dropdowns = HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))
  ...
end

используйте в коде через `Rails.application.config.dropdown [: ключ]

примечание: Iудалит ключ раскрывающегося списка верхнего уровня или добавит его в конце строки загрузки, чтобы вам не приходилось вызывать его каждый раз, когда вы захотите конфигурацию.например,

HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))[:dropdown]

Можно также просто добавить его в константу в вашем приложении. rb:

MY_CONST = HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))
...