Хороший способ назначить защищенные атрибуты - PullRequest
2 голосов
/ 22 июля 2010

Легкая часть:

У меня есть модель с защищенным атрибутом, и у меня есть действие, к которому может обратиться только администратор, как принудительно назначить все атрибуты, поэтому мне не нужно делать что-то подобное:

@post = Post.find(params[:id])
if params[:post].is_a?(Hash) && params[:post][:published]
  @post.published = params[:post].delete(:published) # delete is to skip warning about protected attribute assignment in update_attributes
end
if @order.update_attributes(params[:post])
  …

Тяжелая часть:

У меня есть модель с большим количеством защищенных атрибутов и несколькими типами пользователей, некоторые из них могут назначать только незащищенные атрибуты, некоторые могут изменять только часть защищенных атрибутов, а некоторые - все атрибуты. Как написать небольшой читаемый код в этом случае, не изобретая колесо?

1 Ответ

0 голосов
/ 22 июля 2010

Ну, я могу придумать для вас два способа сделать это.Во-первых, в контроллере: предполагается, что у вас есть метод permitted_to?, который проверяет, разрешено ли пользователю изменять этот атрибут

if params[:post]
  params[:post].each_pair do |key, value|
    @post.send("#{key.to_s}=", value) if @current_user.permitted_to?(:update_attribute, :post, key.to_sym)
  end
  @post.save
end

Другой способ, который, вероятно, не самый лучший, так как вы будетеизмените свойства класса, это означает, что он будет влиять на все экземпляры модели.

в любом случае, предполагая, что вы используете attr_accessible для ограничения атрибутов:

в вашей модели, сделайте это:

 accessible_attributes = self.class.inheritable_attributes.delete(:attr_accessible)

А также может быть хорошей идеей восстановить его после.

 self.class.inheritable_attributes.delete(:attr_accessible) = accessible_attributes

Это работает так же с attr_protected и attr_readonly

И для второй части.Я бы предположил, что у вас есть массив для каждого типа пользователя с атрибутами, которые они могут изменить.

Например:

 self.class.inheritable_attributes[:attr_accessible] = 
      Set.new(@current_user.allowed_attributes(:post))

или

 self.class.inheritable_attributes[:attr_protected] = 
      Set.new(@current_user.restricted_attributes(:post))

, гдеallowed_attributes возвращает массив типа ['parent_id', 'published', 'title']

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...