Расширение ActiveModel :: Serializer методом пользовательских атрибутов - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь создать свой собственный метод attributes с именем secure_attributes, в котором я передаю ему массив атрибутов и минимальный уровень, который должен иметь авторизованный пользователь для просмотра этих атрибутов. Я передаю текущий уровень авторизованного пользователя как instance_option. Я хотел бы расширить класс Serializer, чтобы я мог использовать этот метод в нескольких сериализаторах, но у меня возникли проблемы.

Вот что у меня есть:

в config/initializers/secure_attributes.rb

module ActiveModel
  class Serializer
    def self.secure_attributes(attributes={}, minimum_level)

      attributes.delete_if {|attr| attr == :attribute_name } unless has_access?(minimum_level)

      attributes.each_with_object({}) do |name, hash|
        unless self.class._fragmented
          hash[name] = send(name)
        else
          hash[name] = self.class._fragmented.public_send(name)
        end
      end
    end
  end
end

и затем в отдельном сериализаторе у меня есть такие вещи:

secure_attributes([:id, :name, :password_hint], :guest)

, а затем

  def has_access?(minimum_level=nil)
    return false unless minimum_level
    return true # based on a bunch of logic...
  end

Но очевидно, что secure_attributes не может видеть метод has_access?, и если я помещу has_access в класс Serializer, он не сможет получить доступ к instance_options.

Есть идеи, как мне добиться того, что мне нужно?

1 Ответ

0 голосов
/ 02 сентября 2018

Может быть, вы хотите сделать следующее - но я все еще не понимаю вашу настоящую цель, поскольку вы никогда ничего не делали с атрибутами, а вызывали их:

module ActiveRecord
  class JoshsSerializer < Serializer
    class << self
      def secure_attributes(attributes={}, minimum_level)
        @secure_attributes = attributes
        @minimum_level = minimum_level
      end
      attr_reader :minimum_level, :secure_attributes
    end

    def initialize(attr, options)
      super attr, options
      secure_attributes = self.class.secure_attributes.dup
      secure_attributes.delete :attribute_name unless has_access?(self.class.minimum_level)
      secure_attributes.each_with_object({}) do |name, hash|
      if self.class._fragmented
        hash[name] = self.class._fragmented.public_send(name)
      else
        hash[name] = send(name)
      end
    end

    def has_access?(minimum_level=nil)
      return false unless minimum_level
      return true # based on a bunch of logic...
    end
  end
end
...