I'm using Inherited Resources for my Rails 2.3 web service app. It's a great library which is part of Rails 3.
I'm trying to figure out the best practice for outputting the result.
class Api::ItemsController < InheritedResources::Base
respond_to :xml, :json
def create
@error = nil
@error = not_authorized if !@user
@error = not_enough_data("item") if params[:item].nil?
@item = Item.new(params[:item])
@item.user_id = @user.id
if !@item.save
@error = validation_error(@item.errors)
end
if !@error.nil?
respond_with(@error)
els开发者_Python百科e
respond_with(@swarm)
end
end
end
It works well when the request is successful. However, when there's any error, I get a "Template is missing" error. @error is basically a hash of message and status, e.g. {:message => "Not authorized", :status => 401}
. It seems respond_with
only calls to_xml
or to_json
with the particular model the controller is associated with.
What is an elegant way to handle this? I want to avoid creating a template file for each action and each format (create.xml.erb and create.json.erb in this case)
Basically I want:
/create.json [POST] => {"name": "my name", "id":1} # when successful
/create.json [POST] => {"message" => "Not authorized", "status" => 401} # when not authorized
Thanks in advance.
Few things before we start:
- First off. This is Ruby. You know there's an
unless
command. You can stop doingif !
- Also, you don't have to do the double negative of
if !*.nil?
– Doif *.present?
- You do not need to initiate a variable by making it
nil
. Unless you are setting it in abefore_chain
, which you would just be overwriting it in future calls anyway.
What you will want to do is use the render :json
method. Check the API but it looks something like this:
render :json => { :success => true, :user => @user.to_json(:only => [:name]) }
authorization should be implemented as callback (before_filter), and rest of code should be removed and used as inherited. Only output should be parametrized.Too many custom code here...
精彩评论