简体   繁体   中英

Can I use ActiveRecord::Associations::Preloader / eager loading to load a has_one relationship with dynamic conditions?

I've got this:

class User < ActiveRecord::Base
  has_one :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user

  has_one :latest_action, 
    :class_name=>'Action', 
    :conditions=> Proc.new {["action_at <= ?", self.timezone.now.to_date]},
    :order=>"action_at desc"
end

create_table "actions", :force => true do |t|
  t.date     "action_at"
  t.datetime "created_at"
  t.datetime "updated_at"
end

I would like to do this:

users = User.limit(10)
ActiveRecord::Associations::Preloader.new(users, [:profile => :latest_action]).run 

or this: User.includes(:profile => :latest_action).limit(10).all

However, this fails:

User Load (0.9ms)  SELECT "users".* FROM "users" LIMIT 2
Profile Load (0.8ms)  SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" IN (133622, 133623)
NoMethodError: undefined method `timezone' for #<Class:0x007fc5992152f8>

This works when I'm dealing with a single record:

User.last.profile.latest_action
User Load (0.8ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
Profile Load (0.5ms)  SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = 242222 LIMIT 1
Action Load (0.6ms)  SELECT "actions".* FROM "actions" WHERE "actions"."profile_id" = 231220 AND (action_at <= '2013-08-27') ORDER BY action_at desc LIMIT 1

Can I use a Proc to generate dynamic conditions on a has_one association and use that association in an ActiveRecord::Associations::Preloader call or with eager loaded associations via include?

It seems like in the in pre-loader / eager loading context, self in the conditions proc is a class not an instance.

I am on Rails 3.2.13

Note I realize I could load the association like this, but I can't use that with the preloader

class Profile
  has_many :actions do
    def latest
      where("action_at <= ?", proxy_association.owner.timezone.now.to_date)
    end
  end
end

The problem is that self isn't your object in the has_many , it's the association proxy. If you want the profile object that is referenced in the association, it should be owner (though this is slightly dependent on the version of Rails you're running -- check the documentation for Rails association extensions for more details).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM