Rails 更新时忽略参数

Rails ignoring params on update

无论好坏,我都在使用 Spree 商务 gem。 我向 Spree::Order 模型添加了一个新的属性和列,并且覆盖了 CheckoutController 上的 update_registration 操作。调用 update_registration 操作时,我可以看到通过参数发送的表单内容:

Processing by Spree::CheckoutController#update_registration as HTML "order"=>{"email"=>"xxx@xxx.com", "new_attribute"=>"Bob"}, "commit"=>"Continue to checkout"

这是由一个简单的命令对象处理的:

def call
  order.update(params)
end

之后没有任何日志条目指示任何形式的问题或回滚。 然后我看到:

Spree::Order Update (1.4ms) UPDATE "spree_orders" SET "email" = , "updated_at" = WHERE "spree_orders"."id" = [["email", "xxx@xxx.com"], ["updated_at", "2020-07-23 11:43:29.461912"], ["id", 338]]

哪个成功了。 看起来,模型上的更新方法忽略了新属性。我可以通过数据库中的控制台确认这一点。

我有说明所需行为的规范,并且确实在本地有效。 毫不夸张地说,我正在撕扯我的头发,而且我没有那么多开始。 这不是我的第一个 Rails 牛仔竞技表演,但我无法理解这里发生的事情。很奇怪。

您需要将新属性添加到 spree 初始值设定项中的允许属性

# config/initializers/spree.rb
Spree::PermittedAttributes.checkout_attributes << :other_attribute

勾选https://github.com/spree/spree/blob/master/core/lib/spree/core/controller_helpers/strong_parameters.rb#L19

已解决,与强参数无关。 看起来,生产环境和开发环境之间的 class 加载存在差异,这在 Spree 的文档中没有明确说明,甚至没有被引用。

在生产中,我的控制器操作覆盖被默认的 Spree 实现破坏了。碰巧原始代码正在做类似的事情,所以它看起来像是忽略了一个参数。 完全删除我的代码并观察正在执行的更新表明我的代码路径不是 运行.

Spree 中的覆盖模式有些笨拙,根据我的经验,实现自己的路径并使用 Spree 返回 gem 的流程比尝试覆盖更清晰。