我必须设置关联模型(limesurvey)的表名,因为表名是动态的,取决于模型(任务)的属性(survey_id)。
我的当前实现在初始化任务时设置表名:
class task < ActiveRecord::Base
after_initialize :setTablename
has_one :limesurvey
def setTablename
Limesurvey.table_name = "lime_survey_#{self.survey_id}"
end
end
这种实现有效,但它的缺点是,每个任务都会调用setTablename-method,尽管不需要。
如何在加载关联limesurvey之前执行setTablename?
答案 0 :(得分:2)
class Task < ActiveRecord::Base
has_one :limesurvey
def lime_survey
@table_name || = (Limesurvey.table_name = "lime_survey_#{self.survey_id}")
limesurvey
end
end
这定义了一个带有下划线的limesurvey版本,但首先检查表名是否已设置。打电话给lime_survey而不是limesurvey,你会得到你要求的效果。
类似于Andy建议的方法。但是,虽然关联只是一种方法,但我不确定你可以重新定义它并调用super,因为它不是父类(或模块)中的方法。
答案 1 :(得分:0)
关联只是模型中包含的模块中定义的方法,因此您可以像其他方法一样覆盖它们
class Task < ActiveRecord::Base
has_one :limesurvey
def limesurvey
# do something here...
super
end
end
然而,正如人们在关于这个问题的评论中提到的那样,你所做的是一个非常糟糕的主意。如果您一次有两个任务可用,并试图访问它们上的limesurvey
,会发生什么?
t1 = Task.first
t2 = Task.last
l1 = t1.limesurvey
l2 = t2.limesurvey
l1.update_attributes(foo: "bar")
# Oops... saves into the wrong table...
即使您设法避免在整个应用中的任何位置明确地执行此操作,如果您有两个并发请求,则可能会意外发生!