Reputation: 49743
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"
Upvotes: 2
Views: 1211
Reputation: 43150
Assuming the relation itself works you could try preload
instead of includes
Upvotes: 0
Reputation: 19216
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)
Upvotes: 2
Reputation: 13877
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?
Upvotes: 0