Ruby on rails 强制加载整个关联的Rails查找器?

Ruby on rails 强制加载整个关联的Rails查找器?,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,问题课有很多选择。我需要通过一些属性值(通常是id)找到一个选项 澄清一下:父记录(问题)传递给不同的对象和方法,它们使用不同的属性和值搜索子记录 我可以做question.choices.find(choice\u id),但每次都会生成一个SQL查询 知道问题通常只有很少的选择,而且在一个父记录上会有许多不同的搜索,我怀疑在Ruby中加载整个关联和搜索会更便宜: question.choices.detect{|choice| choice.id == some_choice_id} De

问题课有很多选择。我需要通过一些属性值(通常是id)找到一个选项

澄清一下:父记录(问题)传递给不同的对象和方法,它们使用不同的属性和值搜索子记录

我可以做
question.choices.find(choice\u id)
,但每次都会生成一个SQL查询

知道问题通常只有很少的选择,而且在一个父记录上会有许多不同的搜索,我怀疑在Ruby中加载整个关联和搜索会更便宜:

question.choices.detect{|choice| choice.id == some_choice_id}
Detect来自Enumerable,并强制Rails在第一次调用时加载关联(并在将来的搜索中使用缓存数据)。这也很好地处理了快速加载:我可以做问题。全部(包括:选择)和将整个树加载两个查询,然后搜索速度非常快。不过它读起来不太好

如果我想模拟发现,它会变得更加毛茸茸的!行为:

question.choices.detect{|choice| choice.id == choice_id} or raise ActiveRecord::RecordNotFound.new
这正是我想要的,我只是在寻找更好的语法


Rails是否提供了这样的动态查找程序(在第一次查询时强制加载整个关联,然后搜索这个预加载集)?

我怀疑我缺少Rails中烘焙的或流行gem中可用的东西。如果不是这样的话,我只需要滚动我自己的助手:

Enumerable.module_eval do
  def select_by(attribute_name, value)
    detect do |item|
      item.send(attribute_name) == value
    end
  end

  def select_by!(attribute_name, value)
    select_by(attribute_name, value) \
      or raise StandardError.new("can't find item with #{attribute_name} equal to #{value} in #{self.inspect}")
  end
end
用途如下:

question.choices.select_by(:id, 7)
user.question.select_by(:name, "Is it shiny?")

我相信您想要的被称为“急切加载”,它是使用
.includes
方法实现的

@questions = Question.includes(:choices).all

将生成一个执行内部联接的查询,返回问题及其每个选项。这假设您已经在模型中声明了关系。大概你会限定这个where子句而不是
。all

我会保留
find
。数据库正是为这类任务而创建的,而ruby不是。Nooo!:-)。除非我遗漏了什么,否则你想要的是烤进去的——而且非常美味。请看下面的答案。所以,当我有选择的问题时,我仍然必须找到具有我正在寻找的属性值的问题,如果找不到,则引发异常。是的,我确实想要即时加载(见问题),但我正在寻找一种有效的方法来搜索即时加载的树,而不必每次都点击DB。糟糕的是,我没有仔细阅读这个问题。正如您所说,即时加载是减少SQL查询数量的正确方法,但我不清楚为什么不能使用
.joins
.where
进行筛选,以找到您想要的(或不想要的)。对。我事先不知道所有的搜索和条件。不同的合作者对象可能要求不同的选择。我更新了问题-谢谢你指出这一点。