Topic: Reload/reinitialize a model association?
Is there a way to reload or reinitialize a model association once an application is running?
class Project < ActiveRecord::Basehas_many :milestones,
:conditions => ["milestone_status_id = ?", MilestoneStatus.find_by_name("Active")]end
It appears that Rails will define the association while the application is initializing, and then continue to use that definition until the application exits. This will cause an undesired association if the value "Active" cannot be found in the associated model. I tripped across this behavior during a migration. A run through the log revealed that Rails has defined the association as "milestone_status_id = nil" because the entry for "Active" had not been added to the database while the migration process was initializing. The plan, of course, is to add "Active" to the table during the migration, but by then it is too late.
Furthermore, the :conditions portion of this association will throw "table not found" errors if attempting to rebuild the database via migrations. The rake db:migrate process will exit during environment initialization.
The knee-jerk solution is to use "MilestoneStatus.find_or_create_by_name("Active"). While that would solve the erroneous "milestone_status_id = nil" definition, it doesn't address the "table not found" error when migrating and the MilestoneStatus table hasn't been created yet.
Here's a brutish version of the association that handles the "table not found" error, but it also highlights the need to reload/reinitialize the association:
class Project < ActiveRecord::Basehas_many :milestones,
:conditions => ["milestone_status_id = ?", MilestoneStatus.table_exists? ? MilestoneStatus.find_or_create_by_name("Active") : 0]end
If the MilestoneStatus table has been created, Rails adds/finds "Active" to the table and generates the correct association definition. Otherwise the :conditions line is defined as "milestone_status_id = 0" (which should never return a matching record).
I know the script/console has the handy reload! command, but that seems to have a bug correctly processing includes from the lib folder. And it's also not available from inside a running application or migration.
Of course, I could be going about this all wrong. If that's the case, please tell me! ![]()
edits: cleaned up association examples to remove superfluous code
Last edited by GG Crew (2008-07-28 13:45:05)