Handle validation errors
It seems for now roar-rails' responder doesn't handle validation errors transparently (correct me if I'm wrong) like rails' builtin responder does, see ActionController::Responder docs. Today I write this:
def create
singer = Singer.new(params[:singer])
if singer.save
respond_with singer
else
render json: { message: "Validation Failed", errors: singer.errors }.to_json
end
end
but I'd like this to automatically happen (depending if resource has_errors?..) so we can write this:
def create
respond_with Singer.create(params[:singer])
end
Could you :
- confirm this doesn't work like that for now ? (just tested it with rails 4 / ruby 2.0)
- tell me if this could be interesting or if it's achievable in an other way ?
If it sounds good I can work on that and submit a pull request in a few weeks.
@apotonick +1. Seems like it doesn't look for a Representer when there is a validation error. That's right?
That would be an ActiveModel-related extension of Roar. How would the output of the errors property look like?
FYI, I've solved this with redefined render method in base controller class.
I needed one-level errors hash in my API, instead of 2-level ActiveModel::Errors hash.
{"errors" => ["full error message"]} instead of {"errors" => { "base" => ["error message"]}}
def render(*args)
options = args.dup.extract_options!
if options[:json] && options[:json].is_a?(Hash) &&
options[:json][:errors].is_a?(ActiveModel::Errors)
options[:json][:errors] = options[:json][:errors].full_messages
super options
else
super
end
end
If you want to return a generic errors document, there should be a generic Representer::JSON::Errors that kicks in when respond_with (or whatever renders) detects an error.
Introducing that, you wouldn't have to override render but could simply provide an optional errors representer.
I guess it won't work with current implementation of roar-rails.
The main issue with Roar::Rails::Responder is that it gets control only on rendering model (overrides display).
Rails won't render resource if it has errors (https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/responder.rb#L179). It will explicitly call resource.errors, which are not decorated.
I think that we can try to decorate resource earlier to take control over errors method.