【问题标题】:Selecting ActiveRecord object by parent attribute通过父属性选择 ActiveRecord 对象
【发布时间】:2014-12-10 04:59:42
【问题描述】:

我的 Rails/Heroku/Postgres 应用中有一个 Item 模型,它充当文档,带有一些文本、一个 removed 标志和许多名为 Versions 的子模型。

我的生产数据库中有数百万行 Version 对象,其中父 Itemremoved 标志被用户设置为 yes,我想从数据库中删除这些版本 (并将item 对象留在原处)。

我正在努力选择父项的 removed 标志设置为 true 的所有版本。这是我在version.rb 中的代码:

Version.all(:joins => :item, :limit => 20, conditions: { :items => { :removed => true } } ).each do |v|
  v.delete
end

产生这个:

SELECT "versions".* FROM "versions" INNER JOIN "items" ON "items"."id" = "versions"."item_id" WHERE "items"."removed" = 't' LIMIT 20
DELETE FROM "versions" WHERE "versions"."id" = 1
... lots of DELETE FROM "versions"

当我在本地运行它时,它只会删除版本对象,但是当我在 Heroku Postgres 中将第一个 SQL 语句作为数据剪辑运行时,它也会选择项目对象。我知道内部联接是为了从两个表中进行选择,但我真的不明白这里发生了什么。我需要保持 item 对象完好无损。任何帮助将不胜感激!

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord heroku


    【解决方案1】:

    这可能只是一种风格,但我会这样写查询:

    Version.joins(:item).where(items: { removed: true })
    

    这个 Rails 和它生成的 sql 都不应该返回任何 Items。我想这是引入怪异的数据剪辑。我会尝试在本地拉下您的数据库并在 Rails 控制台中本地运行它。

    另外,一旦你确定它只返回你想要的,你可以通过这样做来加快这个过程:Version.joins(:item).where(items: { removed: true }).destroy_all

    这将避开 Rails(并避免触发任何回调),只需在同一个 sql 查询中执行 find 和 destroy。

    【讨论】:

    • 这是一个很好的答案,但根据api.rubyonrails.org/classes/ActiveRecord/… 它是delete_all 更有效(避免回调)。我会做更多的研究,可能会接受这个答案。谢谢!
    • 另一个问题是destroy_all 不能与limit 一起使用。没有限制,查询将永远运行。有什么想法可以编辑您的代码以包含限制吗?
    • 确实,你是对的。我通常更喜欢使用 destroy_all 并通过 Rails,除非我完全确定我不想要回调。
    • 这似乎是额外的工作,但我怀疑它相当有效:ids = Version.joins(:item).where(items: { removed: true }).limit(20).pluck(:id) 然后Version.where(id: ids).delete_all
    • 产生SELECT id FROM "versions" INNER JOIN "items" ON "items"."id" = "versions"."item_id" WHERE "items"."removed" = 't' LIMIT 20 导致此错误ActiveRecord::StatementInvalid: PG::Error: ERROR: column reference "id" is ambiguous。我把它改成了pluck("versions.id"),效果很好
    猜你喜欢
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多