Implementing a Lookup Table in Rails

Implementing a lookup table in Rails

I encountered the same problem as you, and solved it by creating a gem that adds a dynamic lookup table transparently into the model. I've blogged about it here: http://www.codelord.net/2011/08/09/guest-post-lookup-tables-with-ruby-on-rails/

And the code is here: https://github.com/Nimster/RailsLookup

How to best implement a lookup table in Rails

One approach is to not join the two tables, treat them as separate models.

In the trade model, you have the currency of the trade and a desired cross_rate.

In your Trade model, include the following method.

def get_cross_rate_report_for cross_rate
xrate = CrossRate.where("curr_a == ? and curr_b == ?", currency, cross_rate).first().rate
r = trade.price * xrate
# add pretty print code here
end

Note that I have not tested this, the key is the where condition that enables you to filter results by two columns and return a CrossRate model, on which you then request the rate. Refer to here

For faster lookups, I would add indexes to the CrossRate table. Look here for guidance and sample code (ctrl-f and search 'index').

generating a hash lookup table for indexes of objects in array

How about this:

Hash[array.zip 0..array.length]

Rails Polymorphic with Lookup Table

Ok, after 6.5 hrs, I managed to figure this out. I used the inherited_resources gem to help with the controllers. To recap, I wanted to be able to add Genres to Artists and Bands through a polymorphic relationship, i.e. Genres would be a lookup table, and Genreings would be a polymorphic model that contains genres for Artists and Bands. Below is the code that worked for me:

# Generate some scaffolding
rails generate scaffold Artist name:string
rails generate scaffold Band name:string
rails generate scaffold Genre name:string
rails generate scaffold Genreing genre_id:integer genreable_id:integer genreable_type:string

# Models
class Artist < ActiveRecord::Base
has_many :genreings, :as => :genreable
has_many :genres, :through => :genreings
end

class Band < ActiveRecord::Base
has_many :genreings, :as => :genreable
has_many :genres, :through => :genreings
end

class Genre < ActiveRecord::Base
attr_accessible :name
has_many :genreings
end

class Genreing < ActiveRecord::Base
attr_accessible :genre, :genre_id, :genreable, :genreable_type, :genreable_id
belongs_to :genre
belongs_to :genreable, :polymorphic => true
end

# Controller
class GenreingsController < InheritedResources::Base
belongs_to :genreable, :polymorphic => true
end

# Artist Form View
= simple_form_for(@artist) do |f|

.inputs
= f.input :name
= f.association :genres, :as => :check_boxes

.actions
= f.button :submit

# Band Form View
... (Similar to Artist)

Cannot retrieve lookup values correctly

Just another way to show the value is @status = Lookup.find(@course.status).lookup_text

Why not to try use classes for different lookups:

class CourseStatus < ActiveRecord::Base
set_table_name "lookups"
default_scope where("table_name = 'course' and field_name = 'status'")
end

class Course
belongs_to :course_status
end

You then can use:

CourseStatus.all # e.g. to fill select options
Course.first.course_status.lookup_text # => "Active" or smth else

Or without classes:

class Lookup
def self._by_table_and_field(table, field)
['table_name = ? and field_name = ?', table, field]
end

scope :by_table_and_field, lambda { |table, field|
where(Lookup._by_table_and_field(table, field))
}
end

class Course
belongs_to :status, class_name: 'Lookup', conditions: Lookup._by_table_and_field('course', 'status')
end

Lookup.by_table_and_field('course', 'status').all
Course.first.status.lookup_text

Best way to implement many-to-many lookup table with user-entered data

If you have one user and several contact method possibilities, it's most probably a one-to-many relationship. (I would avoid many-to-many wherever you can, because of the additional complexity and the slow down of querying such models.)

users_table 
id INTEGER
name VARCHAR
etc.

contacts_table
user_id INTEGER -- foreign key on user.id
contact_method ENUM('email', 'phone', 'mail', 'other')
contact_address VARCHAR
etc.

Static lookup table (litteral bit map)

require 'json'

table = {
"00" => ["Fan1", "Fan2", "Fan3"],
"01" => ["Hum1", "Hum2", "Fan5"],
}

max_binary_digits = table.first[1].size

data = [
%Q[{"address": "00","data":"FF"}],
%Q[{"address": "01","data":"00"}],
%Q[{"address": "01","data":"03"}],
]

data.each do |str|
hash = JSON.parse(str)
address = hash["address"]
number = hash["data"].to_i(16)
binary_str = sprintf("%0.8b", number)
p binary_str

binary_str.reverse.each_char.with_index do |char, i|
break if i+1 > max_binary_digits
puts %Q[{"element":#{table[address][i]},"data":{"type":"STAT","state":"#{char}"}}}]
end

puts "-" * 20
end

--output:--
"11111111"
{"element":Fan1,"data":{"type":"STAT","state":"1"}}}
{"element":Fan2,"data":{"type":"STAT","state":"1"}}}
{"element":Fan3,"data":{"type":"STAT","state":"1"}}}
--------------------
"00000000"
{"element":Hum1,"data":{"type":"STAT","state":"0"}}}
{"element":Hum2,"data":{"type":"STAT","state":"0"}}}
{"element":Fan5,"data":{"type":"STAT","state":"0"}}}
--------------------
"00000011"
{"element":Hum1,"data":{"type":"STAT","state":"1"}}}
{"element":Hum2,"data":{"type":"STAT","state":"1"}}}
{"element":Fan5,"data":{"type":"STAT","state":"0"}}}
--------------------

My answer assumes Bit1 in your table is the least significant bit, if that is not the case remove .reverse in the code.

You can ask me anything you want about the code.



Related Topics



Leave a reply



Submit