Rails的includes()不适用于动态关联条件

时间:2012-05-08 16:10:06

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord associations

在多租户应用上工作,我的大多数模型都有一个tenant_id字段,以便通过查找关联(current_tenant.applications.find(params[:id]))来确保读取权限:

class Application < ActiveRecord::Base
  belongs_to :tenant
  has_many :app_questions, :conditions => proc {{:tenant_id => tenant_id}}, :dependent => :destroy
end

我喜欢这样可以让我优雅地创建一个自动设置tenant_id的新AppQuestion:

@application = current_tenant.applications.find(params[:app_question][:application_id])
@question = @application.app_questions.build(params[:app_question])
#...

问题是,当我尝试使用includes()急切加载关联时,会抛出错误:

current_tenant.applications.where(:id => params[:id]).includes(:app_questions => :app_choices).first

NoMethodError (undefined method `tenant_id' for #<Class:0x007fbffd4a9420>):
  app/models/application.rb:7:in `block in <class:Application>'

我可以重构,以便我不必在关联条件下进行proc,但我想知道是否有人有更好的解决方案。

ref does say:“如果需要在运行时动态评估条件,请使用proc”

3 个答案:

答案 0 :(得分:2)

我回答了另一个问题的更多细节,试图解释为什么这不起作用。

当他们说动态是因为proc可以在运行时执行,但Application类的现有实例的上下文中,因为它在您调用时不存在这种关系

Application.where(:id => params[:id]).includes(:app_questions => :app_choices)

答案 1 :(得分:0)

参考资料中未记录:conditions接受proc的能力。我怀疑它不会像你猜测的那样起作用。

:conditions接受SQL WHERE子句或可以打开的哈希。它被插入到获取:app_questions记录的SQL中,如果它是proc,则只调用一次以获取要构造的SQL语句的片段。

查看数据库关系可能会有所帮助。 app_questions应该链接到租户或应用程序吗?

答案 2 :(得分:0)

假设关系本身有效,您可以尝试preload而不是includes