如何通过嵌套的has_many搜索?

时间:2016-04-13 13:51:07

标签: ruby-on-rails has-many-through

这就是我现在所拥有的:

class Pokemon < ActiveRecord::Base
  has_many :pokemon_moves, dependent: :destroy
  has_many :moves, through: :pokemon_moves
end

class PokemonMove < ActiveRecord::Base
  belongs_to :pokemon
  belongs_to :move
end

class Move < ActiveRecord::Base
  belongs_to :type
end

还有很多其他人,不重要。 我只是想寻找一个可以让Move命名为“pound”和另一个Move“mega-punch”的神奇宝贝

我试过了:

Pokemon.joins(:moves).where(moves: {name: 'pound'}).where(moves: {name: 'mega-punch'})

但没有结果。翻译的SQL是:

SELECT "pokemons".* FROM "pokemons" INNER JOIN "pokemon_moves" ON "pokemon_moves"."pokemon_id" = "pokemons"."id" INNER JOIN "moves" ON "moves"."id" = "pokemon_moves"."move_id" WHERE "moves"."name" = $1 AND "moves"."name" = $2  [["name", "pound"], ["name", "mega-punch"]]

如果我只搜索一个动作,它可以正常工作,但我不能通过两个动作来获得它。

我尝试了很多东西,但所有结果都很糟糕。 当然,我有一个有神奇宝贝的神奇宝贝,如果我这样做Pokemon.find_by_name('golurk').moves我可以找回这两个动作。

谢谢!

更新1: 我只需使用&运算符

就可以了
Pokemon.joins(:moves).where(moves: {name: 'pound'}) & Pokemon.joins(:moves).where(moves: {name: 'mega-punch'})

但它真的没有效率,而且我很确定我们能找到更好的方法。

1 个答案:

答案 0 :(得分:0)

您没有获得结果的原因是因为您正在搜索名称为pound且名称为mega punch的移动。

将您的代码更改为:

Pokemon.joins(:moves).where(moves: {name: ['pound', 'mega-punch']})

链接where会在您的sql中生成AND。如果你想要OR,可以使用上面例子中的数组,也可以编写自己的sql。