Ruby и Rails: переменные метапрограммирования становятся методами класса - PullRequest
1 голос
/ 20 февраля 2012

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

В таблице базы данных для модели Configuration у меня есть следующие данные.

---------------------------------------------------------
variable_name as string     |  value in text
                            |
company_name                |  MyCompany
welcome_text                |  Welcome to MyCompany's App!
email_order_text            |  You've just created an account with MyCompany.
year_since                  |  2012
----------------------------------------------------------

class Configuration  < ActiveRecord::Base

    #nothing here yet

end

----------------------------------------------------------

В настоящее время единственный способ доступа к company_name - это выполнить в консоли rails следующее:

configuration_company_name = Configuration.find_by_variable_name("company_name")
configuration_company_name.company_name

> "MyCompany"

Я думаю, что это неприемлемый способ сделать что-то.Во-первых, он будет обращаться к базе данных каждый раз, когда кто-то проверяет название компании.Я думаю, что если бы я мог загрузить его, когда приложение запустится и ему не нужно будет снова обращаться к нему, потому что оно находится в памяти, то это было бы лучше.Как я могу сделать что-то более динамичное, чтобы я мог получить доступ к значению «MyCompany» следующим образом.

Configuration.company_name

> "MyCompany"

Причина, по которой это делается, - дать возможность быстрой настройки приложения.

Ответы [ 3 ]

5 голосов
/ 20 февраля 2012
class Configuration  < ActiveRecord::Base
  # loads all the configuration variables to an in-memory
  # static hash during the first access. 
  def self.[](n)
    @config ||= {}.tap { |h| Configuration.all.each{ h[variable_name] = c.value}}
    @config[n]
  end
end

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

Configuration["company_name"]

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

Если вы хотите получить доступ к параметру конфигурации как метод класса:

class Configuration  < ActiveRecord::Base

 klass = class << self; self; end
 Configuration.all.each{|c| klass.send(:define_method, c.variable_name){c.value}}

end

СейчасВы можете получить доступ к параметру следующим образом:

Configuration.company_name
0 голосов
/ 20 февраля 2012

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

0 голосов
/ 20 февраля 2012

Здесь вы ошибаетесь: никогда не будет Configuration.company_name , это как доступ к свойству Class вместо свойства Object / Instance ,

Это должен быть экземпляр класса конфигурации. Было бы несколько приемлемо использовать метод @ KandagaBoggu в другом ответе, но доступ к базе данных по-прежнему почти каждый раз или из кэша запросов Active Record. Но кэш запросов AR живет в течение определенного действия (т.е. запроса). Вы можете использовать что-то вроде Memcached, чтобы объекты выживали дольше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...