除了在一个字段外,我怎么能禁止更新?

Nic*_*ick 13 ruby activerecord ruby-on-rails

我一直在模型中使用它来阻止对某些模型的更新:

def update
  self.errors.add_to_base( "Cannot update a #{ self.to_s }" )
end
Run Code Online (Sandbox Code Playgroud)

我现在正在编写一个插件,为模型提供一些额外的功能,我需要更新模型中的一个字段.如果我没有使用插件,我会直接在模型中执行此操作...

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

我不能从我的插件中做同样的事情,因为我不知道更新行为是ActiveRecord的默认值,还是已被覆盖以防止更新.还有另一种方法可以阻止记录更新,同时允许我覆盖特定字段(并且仅在我的插件应用于此模型的实例中).

zai*_*ius 12

首先,你应该为这种事情使用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
Run Code Online (Sandbox Code Playgroud)

  • 在rails 3.*中,通过`self.errors.add:base,"无法更新......"添加错误 (4认同)
  • 我想你可能希望if子句更改为`返回true如果self.changed | self.updatabale_attributes == self.updatabale_attributes`,这样你也可以更新updatable_attributes的子集. (2认同)

mar*_*ers 6

这里的游戏晚了,但对于查看此问题的人,您可以使用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
Run Code Online (Sandbox Code Playgroud)