Mateu
Mateu

Reputation: 2698

where to place a controller helper class in a rails app

My rails application has a json api. Operation on this api may return an error. I'm currently using something like:

respond_with({:success=>false, :message=>"error_message"}, :status=>400, :location=>nil)

in the controller

I want to make this nicer. Therefore, I decided to create an error class, and its view, so I can do something like this in controllers:

error.new({message=>"my message", :status =>400})

render error

My question is. Where should I place this ApiError class?

I don't like to put it on models folder, because is kind of a helper for controllers for the api. Not a general application model.

Upvotes: 0

Views: 160

Answers (1)

deefour
deefour

Reputation: 35370

I namespace a class like this after my application and put it in lib/my_app/. For example if your app is FooBar I'd have a folder lib/foo_bar/api and define your class in lib/foo_bar/api/error.rb as

class FooBar::Api::Error
  # ...
end

This can be invoked with FooBar::Api::Error.new(...)

If you choose to go this route, you'll need to add lib/ to your config.autoload_paths in config/application.rb

config.autoload_paths += Dir["#{config.root}/lib"]

Do you know how could I make render error code return the error status code? not using (:status => error.status)

Sure, but to my knowledge you can't just pass error. You'd have to call something like

error = FooBar::Api::Error.new({ message: "Some error message" }, status: :bad_request)

render *error.to_a

You'd then have to define a to_a method on FooBar::Api::Error

class FooBar::Api::Error
  def initialize(data={}, options={})
    @data = data
    @options.reverse_merge! status: 200
  end

  def to_a
    [@data, @options]
  end
end

When you call error.to_a you'll get back an Array which will contain a list of arguments to pass to render. The * on the render line above is the Splat operator (learn more here), expanding the Array into a list of arguments to pass to render instead of sending the entire returned Array as the first argument.

Upvotes: 2

Related Questions