2010-11-16 54 views
13

我已經阻止更新某些車型通過在模型中使用這樣的:如何禁止更新,除了一個字段?

def update 
    self.errors.add_to_base("Cannot update a #{ self.to_s }") 
end 

我現在寫一個插件,提供一些額外的功能模型,我需要在更新一個場模型。如果我不使用插件我會這樣直接在模型...

def update 
    if self.changed == ['my_field'] 
    super 
    else 
    self.errors.add_to_base("Cannot update a #{ self.to_s }")  
    end 
end 

我不能做同樣的從我的插件,因爲我不知道如果更新行爲是默認的ActiveRecord或者已被覆蓋以防止更新。是否有另一種方法來阻止記錄更新,同時允許我重寫特定的字段(並且僅在插件應用於此模型的情況下)。

回答

10

首先,你應該使用before_update回調來做那種事情,而不是重寫更新。其次,您可以將可更新屬性存儲在模型上,然後使用插件更新它們。我只是在瀏覽器中寫這個,所以可能是錯的。

attr_accessor :updatable_attributes 
    before_update :prevent_update 

    private 
    def prevent_update 
    return true if self.changed == self.updatable_attributes 
    self.errors.add_to_base "Cannot update a #{ self.to_s }" 
    false 
    end 
end 
+0

謝謝。我意識到需要我的prevent_update邏輯的模型也是那些需要插件的模型,所以我已經將整個插件移動到插件中,使用像您所建議的那樣的before_update過濾器。 – Nick 2010-11-19 04:32:48

+4

在rails 3. *中,通過'self.errors.add:base,「添加錯誤,」無法更新...「# – ronen 2012-07-10 14:28:34

+1

我想你可能希望if子句可以返回true,如果self.changed | self。 updatabale_attributes == self.updatabale_attributes',這樣你也可以更新updatable_attributes的一個子集。 – Timo 2014-04-05 06:24:00

0

這是爲了防止質量分配? attr_accessible/attr_protected不會做你需要的嗎?


編輯,只是爲了說明回調的一般觀點。

module MyModule 
    def MyModule.included(base) 
    base.send :alias_method_chain, :prevent_update, :exceptions 
    end 

    def prevent_update_with_exceptions 
    end 
end 

class MyModel < ActiveRecord::Base 
    before_validation :prevent_update 

    def prevent_update 
    end 

    include MyModule 
end 
+0

不,它在模型級別執行業務規則。對除了一個領域以外的每個領域都進行attr_readonly可以完成這項工作,但是相當冗長。 – Nick 2010-11-16 07:58:43

+0

before_validation回調如何?你可以檢查哪些屬性已經改變,如果模型是新的,然後阻止更新? – allan 2010-11-16 08:05:39

+0

不知道我完全理解你的建議......你說要在模型中添加一個before_validation回調來防止更新。然後在我的插件中,我應該怎麼做才能在一個字段上進行更新? – Nick 2010-11-16 08:11:21

4

晚了這裏的比賽,卻爲人們觀察這個問題,你可以使用attr_readonly以允許寫入一個字段上創建,但不允許更新。

http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html

我覺得既然Rails的它已經提供2.0

棘手的部分是,如果你有一個是attr_accessible您有任何屬性列出您的只讀屬性有也(或者你上創建質量分配錯誤):

class Post < ActiveRecord::Base 
    attr_readonly :original_title 
    attr_accessible :latest_title, :original_title 
end 
+0

mdkirby,你可以看看這個嗎?我覺得它與這個答案有關。 http://stackoverflow.com/questions/33357501/rails-attribute-changes-in-spite-of-not-being-in-form – 2015-10-27 00:20:48

0

我只是用那些你希望允許params.require法白名單屬性的軌道。

def update 
    if @model.update(update_model_params) 
    render json: @model, status: :ok 
    else 
    render json: @model.errors, status: :unprocessable_entity 
    end 
end 

private 
    def update_prediction_params 
    params.require(:model).permit(:editable_attribute) 
    end 
相關問題