【问题标题】:update Rails / ActiveRecord / SQL database dynamically动态更新 Rails / ActiveRecord / SQL 数据库
【发布时间】:2019-03-25 22:33:40
【问题描述】:

我有一个充满故事的数据库,每个故事都属于一个用户。

我已经为每个故事设置了一个 user_id 属性。

我最近也为我的所有故事添加了一个 user_name 属性。

现在所有这些 user_name 属性都是 nil。

在控制台中,我可以通过Story.first.user_name = Story.first.user.name 将 user_name 属性设置为第一个故事的 user.name 值。

如何遍历我的 Postgresql 数据库中的所有故事并动态更新每个故事的 user_name 值?

我想使用类似 ActiveRecord 的 update_all 方法,但带有动态参数。

我在 Rails 控制台中尝试过:

Story.update_all('user_name = Story.user.name')

但是返回了:

SQL (36.2ms) UPDATE "stories" SET user_name = Story.user.name ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "user" LINE 1: UPDATE "stories" SET user_name = Story.user.name ^ : UPDATE "stories" SET user_name = Story.user.name from (irb):14

不知道如何在原始 SQL 中使用 FROM,或者如何在 ActiveRecord 中编写正确的命令。

【问题讨论】:

  • 您能否说明您要用于更新数据的逻辑?另外,如果您已经在用户模型中拥有该数据,为什么还需要故事中的字段?您是否有理由要在数据库中复制数据?
  • 在数据库中,我想遍历每个故事,并更新其 user_name 属性。每个故事都属于一个用户,所以我想将每个 user_name 设置为每个故事的 user.name 值。
  • 但是,如果您已经有一个有名字的用户,为什么还要复制这些数据呢?另外,什么时候应该进行这种数据迁移?听起来你只需要写一个数据迁移。
  • 我不想再显示每个故事的所有用户数据,因为这些数据包括电子邮件地址和我在 API 端点中不需要或不想要的其他信息。我只希望每个故事都有一个 user_name 属性。
  • 我的问题是:如何使用 update_all 动态更新属性?

标签: sql ruby-on-rails ruby postgresql rails-activerecord


【解决方案1】:

最简单的方法是遍历 stories 表中的所有记录:

Story.find_each {|story| story.update(user_name: story.user.name)}

如果您的目标不是像 update_all 那样触及时间戳或验证,您可以这样做

Story.find_each {|story| story.update_column(:user_name, story.user.name)}

【讨论】:

  • 谢谢,太好了!我希望使用 update_all 因为它不会更新 updated_at 时间戳字段,根据这里的第一条评论:apidock.com/rails/ActiveRecord/Relation/update_all
  • 有一种方法可以用 sql 做到这一点,但不是那么简单。但是你为什么关心时间戳呢?这是一发不可收拾吗?如果这是在生产数据中,则更建议在迁移中这样做。
  • 这是一次性的,但我在前端的表格中按 updated_at 对我的故事进行排序,所以不想更新他们的时间戳。但是,如果不想在不更新 updated_at 值的情况下更新 user_name 属性,我会将其标记为正确。
  • 有一种方法,但这是一个单独的问题。
  • 这是一个单独的问题吗?我的问题是:如何遍历我的 Postgresql 数据库中的所有故事并动态更新每个故事的 user_name 值?我想使用类似 ActiveRecord 的 update_all 方法,但带有动态参数。
猜你喜欢
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多