roar-rails icon indicating copy to clipboard operation
roar-rails copied to clipboard

Handle validation errors

Open jbbarth opened this issue 12 years ago • 5 comments

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.

jbbarth avatar Aug 15 '13 18:08 jbbarth

@apotonick +1. Seems like it doesn't look for a Representer when there is a validation error. That's right?

fltiago avatar Feb 12 '14 14:02 fltiago

That would be an ActiveModel-related extension of Roar. How would the output of the errors property look like?

apotonick avatar Feb 13 '14 01:02 apotonick

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

cutalion avatar May 22 '14 16:05 cutalion

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.

apotonick avatar May 22 '14 22:05 apotonick

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.

cutalion avatar May 23 '14 07:05 cutalion