Rails' includes() doesn't work with dynamic association conditions

白昼怎懂夜的黑 提交于 2019-12-11 02:19:26

问题


Working on a multi-tenant app where most of my models will have a tenant_id field so I can ensure read permissions by finding through the association (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

I like how this allows me to elegantly create a new AppQuestion with the tenant_id set automatically:

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

Problem is, when I try to use includes() to eager-load the association it throws an error:

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>'

I could refactor so that I don't have to have the proc in the association conditions, but am wondering if anyone has a better solution.

The ref does say: "If you need to evaluate conditions dynamically at runtime, use a proc"


回答1:


I've replied to the other question with more details trying to explain why this cannot work.

When they say dynamic is because the proc can be executed at runtime, but not in the context of an existing instance of the Application class because it doesn't exist when you invoke this relation

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



回答2:


The ability for :conditions to accept a proc isn't documented in the ref. I suspect it doesn't work the way you guessed it might.

:conditions accepts either an SQL WHERE clause, or a hash that can be turned into on. It's inserted into the SQL that gets the :app_questions records, and if it's a proc it's only called once to get the snippet for the SQL statement to be constructed.

It might help to have a look at your database relationships. Should app_questions link to tenants or applications?




回答3:


Assuming the relation itself works you could try preload instead of includes



来源:https://stackoverflow.com/questions/10502307/rails-includes-doesnt-work-with-dynamic-association-conditions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!