【问题标题】:How to limit the number of items that can be added to an ActiveRecord array如何限制可以添加到 ActiveRecord 数组的项目数
【发布时间】:2012-02-09 12:45:26
【问题描述】:

我和这个人Rails: How to limit number of items in has_many association (from Parent)有类似的问题

关键是我想在 Array.push 而不是 has_many 关联的 :before_save 属性上执行此操作。在 Java 中,我可能会将 .windows 设为私有并创建自己的访问器。不确定我是否可以使用作为关联结果可用的 ActiveRecord 方法来做到这一点。

有什么建议吗?

我想要通过的规范是:

it "should not accept anymore windows" do
    channel = Channel.new #with default 3 windows
    channel.windows.length.should == 3
    channel.windows.push Window.new
    channel.windows.length.should == 3
end

【问题讨论】:

  • 不是您问题的答案,但您是否打算让它静默失败(即当您这样做时不会引发任何类型的错误)?
  • 马克:不是这样。虽然那可能会很好。这只是我需要确保创建的窗口不超过 3 个的情况。所以默默地失败并且不添加窗口就可以了。不过,对于我们班的消费者来说,这可能是不可接受的。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

您可以在关联上使用before_add callback(向下滚动到标题“关联回调”)来强制执行该行为

如果任何 before_add 回调抛出异常,对象不会被添加到集合中。与 before_remove 回调相同;如果抛出异常,对象不会被删除。

【讨论】:

  • 这是在另一个线程中建议的。问题是,它允许将其添加到对象中,但在调用 .save 方法时会失败。此外,它不会阻止创建孩子,这意味着我必须实施一个救援块来删除孩子。对于 RoR 来说,这一切似乎有点笨拙
  • 说得太早了。关于它创造一个孩子的第二点是不正确的。但是,我仍然可以根据需要向通道添加任意数量的窗口,并且在我尝试保存对象之前不会引发异常。
  • 赎金.. 虽然这不是我想要的,但考虑到 ActiveRecord 所发生的一切,它最终成为了最好的解决方案。即使我可以覆盖“push”并且我找到了一种方法来做到这一点,我也必须覆盖
【解决方案2】:

比回调好一点,但不像你想要实现的那样干净,那就是做类似channel.windows << elem unless channel.windows.length > N 的事情。

【讨论】:

  • 我喜欢这种语法,但它必须在控制器中,而不是模型中,恕我直言。
【解决方案3】:

你为什么不通过一个方法来控制窗口插入呢,

#chanel.rb
class Chanel
  def add_window(window)
    windows.push window if windows.length < 3
  end
end

【讨论】:

  • 在 Java 中,我做了更多工作,我会将 Channel.windows 设为私有并按照您的建议创建一个 setter。但我不希望我的代码是这样的,以至于有人可以在事后出现,只是将一些东西推到数组上,而没有意识到有一个“特殊”的方法来限制它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-27
  • 2021-03-03
  • 2021-07-10
  • 2015-01-02
  • 2023-01-19
  • 2015-06-12
相关资源
最近更新 更多