preLOAD has_​​many关联与动态条件 [英] Preload has_many associations with dynamic conditions

查看:131
本文介绍了preLOAD has_​​many关联与动态条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个地方模型和事件模型。地方的可以有发生在特定日期的事件

I have a Place model and an Event model. Places can have events that take place on a specific date.

我如何设置我的协会和发现者加载在某一特定日期的所有地方,包括(预先加载)的事件,而N + 1查询问题?

How can I set up my associations and finders to load all places including (eager loading) their events at a specific date without N+1 query problem?

我已经试过什么:

class Place
    has_many :events
end

Place.all.preload(:events).where("events.start_date > '#{time_in_the_future}'")
#ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "events".

Place.all.includes(:events).where("events.start_date > '#{time_in_the_future}'").references(:event)
# only loads places that have an event at the specific date and not all places including their events (if there are any events).

我成功地来到了,做什么,但我想不是动态的(不接受参数)

I successfully came up with an association that does what I want but is not dynamic (does not accept parameters)

class Place
    has_many :events, -> {where("events.start_date > '#{Time.now}'")}
end

Place.all.preload(:events)
# perfect: executes two queries: One to get all 'places' and one to get all 'events' that belong to the places and merges the 'events' into the 'place' objects. 
# But I can't pass time as a parameter, so time is always Time.now (as specified in the has_many association). 
# Place.all.preload(:events).where(xyz) gives wrong results like the examples above.

我的问题是,我不能找到一种方法,preLOAD /急于负载动态条件。因为preLOAD,包括预期的关联名作为参数,并且不可阻挡通过设置参数来细化。至少我发现没有办法做到这一点。

The problem for me is that I can't find a way to preload/eager load with dynamic conditions. Because preload and includes expect the association name as a parameter and can´t be refined with parameters. At least I found no way to do this.

推荐答案

要解决的动态数据的问题,你有没有考虑:

To solve the dynamic date problem, have you considered:

class Event < ActiveRecord::Base

  belongs_to :place

  scope :on_date, lambda {|the_date| where(start_date: the_date) }
  scope :on_or_after, lambda {|the_date| where('start_date >= ?', the_date) }
end

您便可以做到这一点:

@place = Place.find(params[:id]) # let's say...
@place.events.on_date(params[:chosen_date])

您可以结合预先加载的东西,其他人提到过。

You can incorporate the eager loading stuff that others have mentioned too.

这篇关于preLOAD has_​​many关联与动态条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆