ruby-on-rails - rails : how to disable persistence of object temporarily?

标签 ruby-on-rails ruby

freeze禁用更新对象值的能力(在一定程度上)。我如何构建一个方法 User.disable_persistence这将禁用在该对象和关联对象上创建/保存/更新的能力,直接调用(User.save)和间接调用(User.children << child)。

是否有 gem 或简单的方法,例如:

class User < ...
  def disable_persistence
    # magic here (nullify save, and other methods, prevent callbacks etc.)
    class_eval :before_save do 
      errors.add(:base, "Persistence has been disabled for this object")
    end
  end
end

最佳答案

问题看起来很简单。棘手的部分是 and indirectly (User.children << child)一部分。 当父对象(User)是新记录时,这可以很容易地处理。但如果不是那么容易。 这是因为像 user#children << child 这样的语句保存父记录和 children当记录user是新的 但当它不是时不做同样的事情。在后一种情况下,它只保存 child .这个问题没有解决 这个项目,自动,至少现在是这样。开发人员必须禁用 child 上的持久性物体优先 为了在后一种情况下实现这一目标。

参见 author_spec.rb文件。告诉你整个故事是很有帮助的。

我为回答您的 SOW 问题而开发的整个项目位于:https://github.com/pmatsinopoulos/disable_persistence

任何想为此做出贡献的人,请随意。

为方便读者,这里也引用了完成整个技巧的代码:

disable_persistence.rb文件:

module DisablePersistence
  extend ActiveSupport::Concern

  def disable_persistence
    @persistence_disabled = true
  end

  def enable_persistence
    @persistence_disabled = false
  end

  module ClassMethods
    def disable_persistence
      @@class_persistence_disabled = true
    end

    def enable_persistence
      @@class_persistence_disabled = false
    end

    def persistence_disabled?
      @@class_persistence_disabled ||= false
    end

    def persistence_disabled
      persistence_disabled?
    end
  end

  included do
    attr_reader :persistence_disabled
    alias :persistence_disabled? :persistence_disabled

    before_save :can_persist?

    after_initialize do |base|
      base.instance_variable_set(:@persistence_disabled, false)
    end

    def can_persist?
      !persistence_disabled? && !self.class.persistence_disabled?
    end

    protected :can_persist?
  end
end

ActiveRecord::Base.send :include, DisablePersistence

注意事项:

一个。实例将响应:

  1. #disable_persistence
  2. #enable_persistence
  3. #persistence_disabled?

B.该类将响应:

  1. #disable_persistence
  2. #enable_persistence
  3. #persistence_disabled?

C.有一个 protected before_save检查实例是否可以持久化的方法。它检查是否启用了实例和类持久性。如果任何一个被禁用,则不允许实例持续存在。

D.该功能自动包含在所有 ActiveRecord::Base 中类。这是上面的最后一行。你可能不想要那样。如果您不想那样,您必须调用 include DisablePersistence在你所有的ActiveRecord::Base您想要此功能的类(class)。

E.在我链接到的 Rails 项目中,我有一个 initializerrequire s 包含此代码的文件。查看 config/initializers .否则,您将不得不自己要求它。

一些使用示例(假设作者和他们的书):

第一个例子:

author = Author.new
author.disable_persistence
author.save # will return false and nothing will be saved
author.enable_persistence
author.save # will return true and author will be saved

第二个例子:

author = Author.new
author.disable_persistence
book = Book.new
author.books << book
author.save # false and nothing will be saved

第三个例子:

author = Author.new
author.save
book = Book.new
book.disable_persistence
author.books << book # nothing will be saved

第四个例子:

author = Author.new
author.save
book = Book.new
author.disable_persistence
author.books << book # will be saved indeed, because the book has enabled persistency

第五个例子:

author = Author.new
Author.disable_persistence
author.save # will return false and will not save

我希望以上内容能回答您的问题,或者至少在某种程度上有所帮助。

关于ruby-on-rails - rails : how to disable persistence of object temporarily?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17889777/

相关文章:

ruby - 检查两个时间戳是否在 Ruby 中是同一天

ruby - 在 Ruby 中提取部分字符串

ruby-on-rails - 如何在 Rails 模型的构造函数中使用参数

ruby-on-rails - 在任何来源中都找不到 sshkit-1.1.0

ruby-on-rails - VB .NET 中有 Rails partials 的类似物吗?

ruby-on-rails - 如何在一个表中添加对同一模型的多个引用的迁移? ruby /rails

ruby - 如何正确调试 Capybara/Poltergeist?

javascript - 自定义函数的 ruby​​execute_script 导致没有结果

ruby-on-rails - 如何对所有请求实现重定向(在特定条件下)?

ruby-on-rails - 带有多个文件的 Rails file_field_tag 向 Controller 提供随机字符串