gpt4 book ai didi

ruby-on-rails - 在记录更新时访问关联的先前值

转载 作者:行者123 更新时间:2023-12-04 03:06:46 25 4
gpt4 key购买 nike

我有一个包含许多“邀请”的“事件”模型。邀请是通过事件表单上的复选框设置的。更新事件时,我想比较更新前的邀请和更新后的邀请。我想将此作为事件验证的一部分。

我的问题是我似乎无法在任何模型回调或验证中访问旧邀请。此时事务已经开始,并且由于邀请不是事件模型的属性,所以我无法使用 _was 获取旧值。

我考虑过自己尝试使用“after_initialize”回调来存储它。这些回调似乎不尊重“:on”选项,所以我不能只这样做:on :update。我不想在每次初始化对象时都运行它。

有没有更好的方法来解决这个问题?

这是我的更新 Controller 中的代码:

  def update
params[:event][:invited_user_ids] ||= []
if @event.update_attributes(params[:event])
redirect_to @event
else
render action: "edit"
end
end

我的主要目标是让您可以将用户添加到事件中,但不能删除用户。我想验证发布的 invited_user_ids 是否包含当前受邀的所有用户。

--更新
作为临时解决方案,我使用了 :has_many 关联上的 :before_remove 选项。我将其设置为抛出 ActiveRecord::RollBack 异常,以防止用户不请自来。不完全是我想要的,因为我无法显示验证错误,但它确实阻止了它。

谢谢,科尔森

最佳答案

你能用ActiveModel::Dirty吗? ?像这样:

def Event < ActiveRecord::Base
validates :no_invitees_removed

def no_invitees_removed
if invitees.changed? && (invitees - invitees_was).present?
# ... add an error or re-add the missing invitees
end
end
end

编辑:我没有注意到 OP 已经打折 ActiveModel::Dirty 因为它不适用于关联。我的错。

另一种可能性是覆盖 invited_user_ids= 方法以将现有用户 ID 附加到给定数组:

class Event < ActiveRecord::Base
# ...

def invited_user_ids_with_guard=(ids)
self.invited_user_ids_without_guard = self.invited_user_ids.concat(ids).uniq
end
alias_method_chain :invited_user_ids=, :guard
end

这应该仍然适用于您,因为 update_attributes 最终会调用各个 attribute= 方法。


编辑:@corsen 在评论中询问为什么我在此示例中使用 alias_method_chain 而不是 super

调用 super 仅在您覆盖定义在继承链上游的方法时才有效。混合在一个模块中或从另一个类继承提供了一种方法来做到这一点。该模块或类不会直接向派生类“添加”方法。相反,它将自己插入该类的继承链中。然后您可以在派生类中重新定义方法,而不会破坏方法的原始定义(因为它们仍在父类(super class)/模块中)。

在这种情况下,invited_user_ids 未在 Event 的任何祖先上定义。它是通过元编程直接在 Event 类上定义为 ActiveRecord 的一部分。在 invited_user_ids 中调用 super 将导致 NoMethodError,因为它没有父类(super class)定义,并且重新定义该方法会丢失其原始定义。所以 alias_method_chain 确实是在这种情况下实现类似 super 行为的最简单方法。

有时 alias_method_chain 杀伤力过大,会污染您的命名空间,使跟踪堆栈跟踪变得困难。但有时这是在不丢失原始行为的情况下更改方法行为的最佳方式。您只需要了解其中的区别,就可以知道哪个是合适的。

关于ruby-on-rails - 在记录更新时访问关联的先前值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9445755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com