问题描述:

Sorry if my question is stupid, but I spent lot of time searching solution and I didn't find.

I'd like to create an ApiOutputsHandler model without database. So I've created an ActiveModel.

This model will be used for custom responses of my API such as errors (but not only). I've used the send() method to add the attributes to this model, but think it's very crappy...

class ApiOutputsHandler

attr_accessor :status, :type, :message, :api_code, :http_code, :template

ERR_TYPES = {

:permanent_quota_limit => { :type => 'PermanentLimitException', :message => 'Quota limit reached for this action', :api_code => 700, :http_code => 401 }

}

def initialize(data)

data.each do |name, value|

send("#{name}=", value)

end

end

def error()

send('status=','error')

send('template=','api/v1/api_outputs_handler/output')

return self

end

def new

return self

end

end

Then, I instantiate my Object like this

@output = ApiOutputsHandler.new(ApiOutputsHandler::ERR_TYPES[:permanent_quota_limit])

return @output.error()

I'll avec a lot of ERR_TYPES (that's the interest).

Do you think there's a better way to do that ?

When I inspect the created object, it lokks like this:

#<ApiOutputsHandler:0x000000036a6cd0 @type="PermanentLimitException", @message="Quota limit reached for this action">

Do you see the arobase in front of attributes? Why do I get that instead of the common:

#<ApiOutputsHandler:0x000000036a6cd0 type: "PermanentLimitException", message: "Quota limit reached for this action">

thanks for your help!

网友答案:

Yes, there is a better way to do it. Here's how I would go about it:

class ApiOutputsHandler
  attr_accessor :status, :type, :message, :api_code, :http_code, :template

  ERR_TYPES = {
    :permanent_quota_limit => { :type => 'PermanentLimitException', :message => 'Quota limit reached for this action', :api_code => 700, :http_code => 401 } 
  }

  def initialize(data)
    # added it here so that you can pass symbol error code to initializer
    data = ERR_TYPES[data] if data.is_a?(Symbol)

    data.each do |name, value|        
      send("#{name}=", value)  
    end
  end

  def error
    self.status = 'error'
    self.template= 'api/v1/api_outputs_handler/output'
    self
  end
end

This way, you can just pass the symbol error code to the initializer, like this:

handler = ApiOutputsHandler.new(:permanent_quota_limit)

You also can change how your objects looks in console, you just need to redefine the #inspect method. In your case, it might look like this:

def inspect
  "#<#{self.class.name} type: #{type}, message: #{message}>" # etc
end
相关阅读:
Top