Как я могу запретить обновления кроме одного поля? - PullRequest
13 голосов
/ 16 ноября 2010

Я предотвращаю обновления некоторых моделей, используя это в модели:

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 по умолчанию или был переопределен для предотвращения обновлений.Есть ли другой способ предотвратить обновление записей, позволяя мне переопределять для определенного поля (и только в том случае, если мой плагин применяется к этой модели).

Ответы [ 4 ]

12 голосов
/ 17 ноября 2010

Во-первых, вы должны использовать обратный вызов 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
4 голосов
/ 03 сентября 2015

Позднее здесь игра, но для людей, просматривающих этот вопрос, вы можете использовать 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 голосов
/ 23 сентября 2017

Я просто использую метод rails 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
0 голосов
/ 16 ноября 2010

Это для предотвращения массовых назначений?Разве 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...