Dan Dan - 22 days ago 4
Ruby Question

Loading table into an array constant

I have a Rails App that's essentially an invoicing and payment system. Within the application i have 2 tables that hold the misc_charges codes and description (ie: id:1 , code: '01' desc:'Apples' , id:2 , code :'02' , desc: 'Bananas' etc. ) the other table is the credits (ie: id:1 , code: '30' , desc: 'Coupon' , id:2 , code: '31' , desc: 'AAA rebate' etc). These codes are not subject to change very much and we are likely to add codes rather than modify or delete any of them.

Currently, we store the alphanumeric code in the main transaction table. such as '01' , '02' , '30' or '31'. I could have used the id generated by rails/postgresql but the reason why we use the alpha codes is because this data will eventually need to be exported and imported into another system that uses those alphanumeric codes as the primary identifier for the misc charges and credits.

Anyhow, currently in the app, when a user (or an admin) reviews their transaction history or a specific invoice, using the transaction table i get the specific description for an alphanumeric code using a model method.

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

Then in the view i use this:

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

Currently, the application is in development mode and we're doing some testing in a staging environment. We don't have a whole lot of transactions but i can't help but to think that calling the model to show the description for every code is bound to create some performance issues when the transaction count skyrockets or we have multiple users using the App at the same time.

Is there a way to load those codes and descriptions, which will essentially be static most of the time, into an array as a constant? I have seen articles about Ruby on Rails constants that you can define in the application.rb or in the initializers folder but the example i have seen are mostly for static data... not something loaded from a table... Are the models available to pull data from in the application.rb or initializers?

Can it be as simple as doing this

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

or is there something more to it?

Once i have that in an array, how do i go about replacing the Model method call in the view to snatch the proper description?


You are pretty close, though I'd recommend keeping the caching inside that class method:

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

If you need to access the cached ones you can use MiscCharge.instance_variable_get("@misc_charges_by_code") and even clean it out MiscCharge.instance_variable_set("@misc_charges_by_code", {})