2016-10-04 2 views
0

У меня есть приложение Rails, которое по сути является системой выставления счетов и платежей. В приложении есть 2 таблицы, в которых содержатся коды и описание misc_charges (например: id: 1, код: '01' desc: 'Яблоки', id: 2, код: '02 ', desc:' Bananas 'и т. Д.), другая таблица - это кредиты (то есть: id: 1, код: '30', desc: 'Coupon', id: 2, код: '31', desc: 'AAA rebate' и т. д.). Эти коды не подвержены изменениям, и мы скорее всего добавим коды, а не модифицируем или удалим их.Загрузка таблицы в постоянную массив

В настоящее время мы сохраняем буквенно-цифровой код в таблице основных транзакций. таких как «01», «02», «30» или «31». Я мог бы использовать идентификатор, созданный rails/postgresql, но причина, по которой мы используем альфа-коды, состоит в том, что в конечном итоге эти данные должны будут экспортироваться и импортироваться в другую систему, которая использует эти буквенно-цифровые коды в качестве основного идентификатора для различных сборов и кредитов ,

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

class MiscCharge < ActiveRecord::Base 
    def self.get_desc(r_code) 
    result = MiscCharge.select("misc_charges_desc").where("code = ?", r_code) 
    return result[0].misc_charges_desc 
    end 
end 

Тогда в представлении я использую это:

<td> 
    <%if p.type == "R"%> 
    <h5 align ="left"><%=MiscCharge.get_desc(p.code)%></h5> 
    <% else %> 
    <h5 align ="left"><%=Credit.get_desc(p.code)%></h5> 
    <% end %> 
</td> 

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

Есть ли способ загрузить эти коды и описания, которые по большей части будут статическими большую часть времени, в массив как константу? Я видел статьи о константах Ruby on Rails, которые вы можете определить в application.rb или в папке инициализаторов, но пример, который я видел, в основном для статических данных ... не что-то загруженное из таблицы ... Доступны ли модели извлекать данные из application.rb или инициализаторы?

Может ли это быть так просто, как это делает

misc_charges_array = MiscCharge.select(:id, :code, :desc).map {|e| e.attributes.values} 

или есть что-то большее?

Как только у меня есть это в массиве, как мне пойти на замену вызова метода Model в представлении, чтобы вырвать правильное описание?

ответ

1

Вы довольно близко, хотя я бы рекомендовал держать кэширование внутри этого метода класса:

class MiscCharge < ActiveRecord::Base 
    def self.get_desc(r_code) 
    # pre-fill the array 
    @misc_charges_by_code ||= MiscCharge.select(:id, :code, :desc).map {|e| e.attributes.values}.inject({}) {|memo, charge| memo[charge.code] = charge; memo } 
    return @misc_charges_by_code[r_code] if @misc_charges_by_code[r_code] 
    result = MiscCharge.select("misc_charges_desc").where("code = ?", r_code) 
    return @misc_charges_by_code[r_code] = result[0].misc_charges_desc 
    end 
end 

Если вам необходимо получить доступ к кэшированных те, которые вы можете использовать MiscCharge.instance_variable_get("@misc_charges_by_code") и даже очистить его MiscCharge.instance_variable_set("@misc_charges_by_code", {})

0

Ответ Томаса сделал трюк, но мне пришлось немного подкорректировать вещи, но в конечном итоге его работала. Я получил ошибку «неопределенный метод« код »для [2,« Tax Seminar Fee »,« 07 »]: Array«

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

Конечный результат выглядит следующим образом

@misc_charges_by_code ||= MiscCharge.select(:id, :code, :misc_charges_desc).map {|e| e.attributes.values}.inject({}) {|memo, misc| memo[misc[2]] = misc[1]; memo} 
return @misc_charges_by_code[r_code] if @misc_charges_by_code[r_code] 
result = MiscCharge.select("misc_charges_desc").where("code = ?", r_code) 
return @misc_charges_by_code[r_code] = result[0].misc_charges_desc