patternrubyrailsMinor
Dynamic association generation in ActiveRecord
Viewed 0 times
activerecordgenerationassociationdynamic
Problem
I'm developing a Rails-based web interface/API for a large, vendor-supplied, legacy Oracle database. One of the constraints is that I can't change the schema other than adding views, because it still has to support the vendor's application.
The table for customer data has a limited number of columns, and extended attributes are stored in customer_def_field_value. These attributes are defined in customer_def_field_def.
so I end up with the classes:
In order to get associations on Customer for each of the 'custom fields', I have this code in the Customer class:
This works like a charm, but it queries the DB every time a Customer is instantiated in order to generate the method definitions.
It hasn't been a performance issue... yet.
New custom field types aren't added very often, so I think I might be able to do this in an initializer rather than in my model, and just restart the application if new fields have to be added... but I wanted to get some feedback. Thanks!
The table for customer data has a limited number of columns, and extended attributes are stored in customer_def_field_value. These attributes are defined in customer_def_field_def.
so I end up with the classes:
class FieldDef :cust_id
belongs_to :field_def, :foreign_key => :customer_def_field_def_id
endIn order to get associations on Customer for each of the 'custom fields', I have this code in the Customer class:
FieldDef.find_each do |field|
has_one field.symbol, :class_name => 'FieldValue', :foreign_key => :cust_id, :conditions => proc{ "customer_def_field_def_id = #{field.id}"}
accepts_nested_attributes_for field.symbol
delegate :field_value, :to => field.symbol, :prefix => true
delegate :field_value=, :to => field.symbol, :prefix => true
attr_accessor ('set_' + field.symbol.to_s).to_sym
endThis works like a charm, but it queries the DB every time a Customer is instantiated in order to generate the method definitions.
It hasn't been a performance issue... yet.
New custom field types aren't added very often, so I think I might be able to do this in an initializer rather than in my model, and just restart the application if new fields have to be added... but I wanted to get some feedback. Thanks!
Solution
I think the query of the database would only happen once in production mode (the class would get cached, in development mode, the class gets reloaded every request that references a Customer object). You can confirm this by setting:
in your production.rb file and seeing if the query runs more than once. It might be worth having an after_save callback for FieldDef that does the same thing as the "FieldDef.find_each do |field|" block you have so you don't have to restart the server when new FieldDefs are created.
config.log_level = :debugin your production.rb file and seeing if the query runs more than once. It might be worth having an after_save callback for FieldDef that does the same thing as the "FieldDef.find_each do |field|" block you have so you don't have to restart the server when new FieldDefs are created.
Code Snippets
config.log_level = :debugContext
StackExchange Code Review Q#7682, answer score: 4
Revisions (0)
No revisions yet.