防止模型

时间:2016-03-14 14:18:28

标签: ruby-on-rails ruby

我有一个模型,文章,有两个状态,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"

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

2 个答案:

答案 0 :(得分:2)

我会通过在模型中提供验证来实现,而不是在控制器中,如下所示:

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

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

答案 1 :(得分:0)

您可以使用readonly?

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

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

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