2016-03-14 152 views
0

我有一個模型,文章,它有兩個狀態,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

我會通過控制器模型提供一個驗證,而不是像這樣做:

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

我會使用aasm,如果我有超過2個州管理 – tvieira

+0

同意,只爲未來 –

0

您可以使用readonly?

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

這將引發異常,如果你嘗試更新的文章。這是一個很好的設計決定,取決於你的域名。在大多數情況下,我會使用「已發佈」狀態,並讓觀衆能夠看到任何後續編輯完成很像這裏在StackoverFlow上。

如果您打算進行那種跟蹤,則PaperTrail gem非常有用。

+0

另外你可能想要使用[ActiveRecord :: Enum](http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html)來保持模型的狀態。 – max