Im trying to eliminate two tables from my database. The tables are message_sort_options and per_page_options. These tables basically just have 5 records which are options a user can set as their preference in a preferences table. The preferences table has columns like sort_preferences and per_page_preference which both point to a record in the other two tables containing the options. How can i set up the models with virtual attributes and fixed values for the options - eliminating table lookups every time the preferences are looked up?
views:
40answers:
2
A:
Try this:
class MessageSortOption
def self.get_cached_option(id)
# store the hash of the options in a class variable
(@@option_cache ||= Hash[ *all.collect{|o| [o.id, o]}.flatten])[id]
end
end
class PerPageOption
def self.get_cached_option(id)
# store the hash of the options in a class variable
(@@option_cache ||= Hash[ *all.collect{|o| [o.id, o]}.flatten])[id]
end
end
class User
has_one :preference
end
class Preference
def sort_preference
MessageSortOption.get_cached_option(attributes['sort_preference'])
end
def per_page_preference
PerPageOption.get_cached_option(attributes['per_page_preference'])
end
end
Now you can access the preference as follows:
current_user.preference.sort_preference
current_user.preference.per_page_preference
KandadaBoggu
2010-03-25 20:44:02
Sorry, it seems like you've got exactly what I'm looking for, but I'm not sure where to define the options.
Mike
2010-03-25 20:50:55
You still need to store the `options` in your tables but now the data is cached.
KandadaBoggu
2010-03-25 21:22:56
ohh, gotcha. Thanks :)
Mike
2010-03-25 21:24:09
I have added another solution which does not require two tables to store options
KandadaBoggu
2010-03-25 22:49:01
A:
Create a app_config.yml
file in config
directory.
page:
small: 10
medium: 20
large: 30
sort:
name: name DESC
amount: amount ASC
date: created_at DESC
Create UserOptions
class in models directory.
class UserOptions
def self.page_option key
options['page'][key] rescue nil
end
def self.sort_option key
options['sort'][key] rescue nil
end
def self.options
@options ||= YAML.load_file( File.join(RAILS_ROOT,
"config", "app_config.yml")) rescue {}
end
# use this in the view to set the preference
def self.page_collection
option_collection 'page'
end
# use this in the view to set the preference
def self.sort_collection
option_collection 'sort'
end
def self.option_collection key
(options[key]|| {}).to_a
end
end
Configure your models:
class User
has_one :preference
end
class Preference
def sort_preference(default = nil)
UserOptions.sort_option(attributes['sort_preference']) || default
end
def per_page_preference(default = nil)
UserOptions.page_option(attributes['per_page_preference']) || default
end
end
Now you can do the following:
current_user.preference.per_page_preference
# use 10 as the page size if no value is given
current_user.preference.per_page_preference(10)
KandadaBoggu
2010-03-25 22:48:04