ruby on rails - Filtering fields from ActiveRecord/ActiveModel JSON output (by magic!) -


i want filter out specific fields activerecord/activemodel classes when outputting json.

the straightforward way overriding as_json, perhaps so:

def as_json (options = nil)   options ||= {}   super(options.deep_merge({:except => filter_attributes})) end  def filter_attributes   [:password_digest, :some_attribute] end 

this works, it's little verbose , lends not being dry pretty fast. thought nice declare filtered properties magical class method. example:

class user < activerecord::base   include filterjson    has_secure_password   filter_json :password_digest   #... end  module filterjson   extend activesupport::concern    module classmethods     def filter_json (*attributes)       (@filter_attributes ||= set.new).merge(attributes.map(&:to_s))     end      def filter_attributes       @filter_attributes     end   end    def as_json (options = nil)     options ||= {}     super(options.deep_merge({:except => self.class.filter_attributes.to_a}))   end end 

the problem getting deal inheritance properly. let's subclass user:

class secretiveuser < user   filter_json :some_attribute, :another_attribute   #... end 

logically, makes sense filter out :some_attribute, :another_attribute, , :password_digest.

however, filter attributes declared on class. desired end, tried call super within filter_attributes, failed. came this, , it's hack.

def filter_attributes   if superclass.respond_to?(:filter_attributes)     superclass.filter_attributes + @filter_attributes   else     @filter_attributes   end end 

this brittle , not idiomatic, there's "what" i'm trying accomplish. can think of way more correctly (and more elegantly)? thanks!

i think safer solution white-list attributes black-list them. prevent unwanted future attributes added user or someuser making json response because forgot add said attributes filter_json.

you seem looking solution specific inheritance issue. i'm still going point out active_model_serializers, feel saner way manage serialization.

class userserializer < activemodel::serializer   attributes :id, :first_name, :last_name end  class secretuserserializer < userserializer   attributes :secret_attribute, :another_attribute end 

given secretuser s can do

secretuserserializer.new(s).as_json 

and you'll :id, :first_name, :last_name, :secret_attribute, , :another_attribute. inheritance works expected.


Comments

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

javascript - storing input from prompt in array and displaying the array -