【问题标题】:Preventing attributes update in model防止模型中的属性更新
【发布时间】:2016-03-14 14:18:27
【问题描述】:

我有一个模型,文章,它有两个状态,createdfinalized。我允许用户创建文章,但只有在模型的某些属性存在时才能最终确定。

状态本身是我的article.rb 模型的一个属性。鉴于在我的控制器中,我将拥有强大的参数,我想更进一步,防止对对象的调用更新不会更新属性状态,但仍会更新其他属性,如下所示:

article = Article.create!
article.state # => "created"
article.update!(attr1: "attr1", attr2: "attr2", state: "finalized")
article # => attr1: attr2, attr2: attr2, attr3: null, attr4: null, state: "created"
article.update!(attr3:, "attr3", attr4: "attr4", state: "finalized")
article # => attr1: "attr2", attr2: "attr2", attr3: "attr3", 
        #    attr4: "attr4", state: "finalized"

我的想法是防止对象的属性被更新,除非所有必需的属性都存在,但仍然允许用户创建对象而无需预先指定所有属性。我怎样才能做到这一点? (这值得麻烦还是个好主意?)

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    我会通过在模型中而不是在控制器中提供验证来做到这一点,如下所示:

    class Article
      validates :state, exclusion: { in: %w(finalized) },
                unless: Proc.new { |a| a.attr1.present? && a.attr2.present? }
    end
    

    您也可以考虑使用状态机来跟踪文章的状态:https://github.com/aasm/aasm

    【讨论】:

    • 同意,只是为了未来
    【解决方案2】:

    你可以使用readonly?

    class Article < ActiveRecord::Base
      def readonly?
        state != "finalized"
      end
    end
    

    如果您尝试更新文章,这将引发异常。这是否是一个好的设计决定取决于您的领域。在大多数情况下,我会使用“已发布”状态,让查看者能够看到任何后续编辑,就像在 StackoverFlow 上一样。

    如果您打算进行此类跟踪,PaperTrail gem 非常有用。

    【讨论】:

    猜你喜欢
    • 2019-06-06
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多