如何从记录子集中有效地获取has_many值?

时间:2018-04-11 23:50:12

标签: ruby-on-rails sqlite

我有以下课程:

class PinTiming < ApplicationRecord
  belongs_to :pin
  has_many :propagation_segments
  has_many :flags
end

class Pin < ApplicationRecord
  belongs_to :block
  has_many :pin_timings
end

class Block < ApplicationRecord
  belongs_to :comp_report
  has_many :pins
  has_many :pin_timings, through: :pins 
end

我希望能够从块的子集中获取所有pin_timings。我想我需要一个联接,但我一直很难找到正确的语法。

例如,我可以找到我想限制搜索的块:

blocks_of_interest = Block.where("name LIKE ? OR name LIKE ?", "%i\_drv\_16t%", "%i\_cells\_byte%cells%cell%")

当我想找到pin_timings时,我希望我这样搜索:

rise_pin_timings = PinTiming.where("phase LIKE '%R@L%' and source LIKE ?", "%RWL_C_BYTE_#{a}\(%\)")

我想要限制PinTiming查询只考虑可以在blocks_of_interest中找到的PinTimings,或者我希望Block查询返回所有底层的pin_timings,所以我可以在以后进一步过滤它们。我想我想弄清楚如何做两种情况然后选择更快的解决方案。

2 个答案:

答案 0 :(得分:1)

首先你可以获得block_of_interest id:

block_ids = Block.where("name LIKE ? OR name LIKE ?", 
            "%i\_drv\_16t%", "%i\_cells\_byte%cells%cell%").pluck(:id)

然后你可以从这些块id获得所有PinTimming:

PinTiming.joins(pin: :block).where(blocks: { id: block_ids} )

修改

根据max建议,您可以一步完成,而无需先获取块ID:

PinTiming.joins(pin: :block).where(blocks: { 
  id: Block.where("name LIKE ? OR name LIKE ?", 
                  "%i\_drv\_16t%", "%i\_cells\_byte%cells%cell%")} )

答案 1 :(得分:1)

我相信你正在寻找类似的东西:

class PinTiming < ApplicationRecord
  belongs_to :pin
  has_one :block, through: :pin
  has_many :propagation_segments
  has_many :flags
end
PinTiming.joins(:block)
  .where("pin_timings.phase LIKE '%R@L%' AND pin_timings.source LIKE ?", "%RWL_C_BYTE_#{a}\(%\)")
  .where("blocks.name LIKE ? OR blocks.name LIKE ?", "%i\_drv\_16t%", "%i\_cells\_byte%cells%cell%")

请注意,您需要在加入时在WHERE子句中指定表。

如果你真的想拆分它:

blocks = Block.where("blocks.name LIKE ? OR blocks.name LIKE ?", "%i\_drv\_16t%", "%i\_cells\_byte%cells%cell%")
rise_pin_timings = PinTiming.joins(:blocks)
                            .where("pin_timings.phase LIKE '%R@L%' AND pin_timings.source LIKE ?", "%RWL_C_BYTE_#{a}\(%\)")
                            .where(block: { id: blocks})