【问题标题】:Why is the first value of a Rails find_or_create_by block always nil in database?为什么 Rails find_or_create_by 块的第一个值在数据库中总是为零?
【发布时间】:2018-06-21 20:58:37
【问题描述】:

我正在使用find_or_create_by 块。

如果没有找到作为参数传递的带有webinar_id 的 TrainingEvent 记录,Rails 应该使用块中传递的所有属性创建一个新的 TrainingEvent。

Rails 创建记录,但第一个属性在数据库中始终为 nil。

Rails 5.2.0

红宝石 2.4.1p111

TrainingEvent.find_or_create_by(webinar_key: '2345') do |training_event|
  training_event.start_date_time = '2018-07-04 12:00:00',
  training_event.end_date_time = '2018-07-04 13:00:00',
  training_event.published = true,
  training_event.hidden_from_list = false,
  training_event.training_template_id = 349,
  training_event.organizer_key = '6789'
end

start_date_time 不在 SQL 中,最终在数据库中为零。无论哪个属性在块中第一个,其值始终为 nil。

【问题讨论】:

  • (1) 请不要在问题中包含文本的屏幕截图,文本本身会更易于阅读和使用。 (2) 为什么你的代码块中有那么多尾随逗号?

标签: ruby-on-rails ruby activerecord


【解决方案1】:

mu is too short 发现的逗号实际上是导致问题的原因。

这被 Ruby 解释为试图将一个数组分配给start_date_time,其副作用是设置所有其他属性。由于这不是该字段的有效值,因此最终保留为 nil

这似乎源于一个轻微的误解:

Rails 应该使用块中传递的所有属性创建一个新的 TrainingEvent

该块不用于传递属性的列表。该块是在create 的情况下传递新模型对象的代码,以便您可以在保存之前对其进行任何操作。去掉逗号就没事了!


如果您好奇,这里有一个更简单的示例来演示您的代码是如何被解释的:

> x = 1, y = 2

这导致x 具有数组值[1, 2]y 具有值2

【讨论】:

  • 遗憾的是,start_date_time= 方法(以及来自 ActiveRecord 的其他时间戳修改器)在输入不知道如何处理的值时没有大声抱怨。悄悄地将废话转换为nil 是可怕的默认行为。
  • 感谢您的详尽解释,@mikej。你是绝对正确的。现在就像一个魅力。
猜你喜欢
  • 2018-11-02
  • 2022-01-07
  • 1970-01-01
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
  • 1970-01-01
相关资源
最近更新 更多