I'm building a Rails API and finding myself falling into the same patter:
def some_generic_customer_method
#customer = Customer.where(id: params[:id]).first
if #customer.present?
##execute some code
else
respond_to do |format|
msg = {:status => "FAILED", :messages => "Could not find customer"}
format.json { render :json => msg }
end
end
end
Is there a way to code clean my API so I'm don't have this check/failed response every API call? Right now this is being called in every one of my methods
Use before_filter and move fail-check to a private method.
Related
I have this simple Admin controller and I'm trying to display a message after the #reset action is called to give the admin feedback when the action is completed (as it executes de seed.rb file)
The action performs just fine, but I can't get it to display the msg and I get this message in the server log:
ActionController::UnknownFormat (Api::V1::AdminController#reset is missing a template for this request format and variant.
request.formats: ["application/json"]
request.variant: []):
class Api::V1::AdminController < Api::V1::BaseController
before_action :initialize
def seed
#builder.process_file
end
def reset
Rails.application.load_seed do
msg = { :status => "ok" }
respond_to do |format|
format.json { render :json => msg }
end
end
end
private
def initialize
#builder = PaymentBuilder.new
end
end
What am I doing wrong?
EDIT:
I had to declare respond_to :json at the class level of the controller and change the action block to
def reset
Rails.application.load_seed
msg = { :reset => "OK" }
respond_with do |format|
format.json { render :json => msg }
end
end
And it renders fine now.
I guess this is happening because you are rendering inside of the block, I think you can not do that in that way
Want to fetch data from client side,by using an action create,how to fetch data by using post method in create function,My point is how i can get data from client side using create function by post method
def create
respond_to do |format|
#post = Post.new(params[:post])
if #post.save
flash[:notice] = "Prayer Successfully created."
#posts = Post.paginate(page: params[:page],:per_page => 5)
format.json{ render :json => #post, :only=> :content, :location => #post }
else
flash[:notice] = "Error"
#posts = Post.paginate(page: params[:page],:per_page => 5)
format.json{ render :json => #post, :status => :created }
end
end
end
def create_a_post
content = JSON.parse request.body.read
#post = Post.new[:content]
#post.save
end
My code is correct or wrong to fetch data from client side
any one pls solve my pblm
i have problems understanding your english, but i think that i got your question.
so, as far as i understand, you want to send data via a post-request from the client/browser to your rails app.
when you defined Post as a resource, than this is usually done via the create action in your PostsController.
you need to be a little carefull with the names though. there is a difference between resources :posts or resource :post and PostsController and PostController.
make sure that you read the guides about this: http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default
i have no clue what you are trying to do with that create_a_post method. is that supposed to be a helpermethod in the controller?
it's also pretty odd that you are paginating your results in the create method. the usual pattern is to create something and then redirect back to the index action.
There are some instances where I need to both have a template and return error codes when using respond_with in Rails 3.
I have a before filter that is as follows:
def ensure_premium
respond_with("Must be a premium user!", status: 401, location: nil) unless current_user.is_premium?
end
and a create action that does the following:
def create
#wait_list = #hangout.wait_lists.find_or_create_by(user_id: current_user.id)
respond_with(#wait_list) do |format|
format.json {render 'create', status: 201}
end
end
Even though the before filter trips, it still tries to render the template which results in an error. What am I missing to get it to return the right error and status code and not render the template?
You have multiple respond_with's for the create action. But I think more critically, you might need:
def ensure_premium
respond_with :json => {:error => "Must be a premium user!", :status => :unauthorized } unless....
I don't think this is the problem, but make sure in your controller you have
class SomeController < ApplicationController
respond_to :json
I ended up going a different route completely so this question is no longer valid.
I have a subscriber#create method that is only used for ajax submits to it (the html form uses data-remote="true" to do the Ajax. The form does indeed submit and the data ends up in the db but the method throws an error saying that the template was not found.
How can I specify a function as being an Ajax handler in Rails? -- one that doesn't have to render a template, etc.
Here is what the method looks like:
class SubscribersController < ApplicationController
def create
Subscriber.create(:email => params[:email],
:ip_address => request.remote_ip,
:referring_page => request.referer ) unless Subscriber.find_by_email(params[:email])
end
end
You should handle the call in your respond_to properly.
...
respond_to do |format|
format.html
format.js { :nothing => true }
end
The thing it, you should probably return something. Even if it is an AJAX call, you should send something back to let the caller know that the creation was a success.
def create
#subscriber = Subscriber.new(#your params)
respond_to do |format|
if #subscriber.save
format.js { render :json => #subscriber, :status => :created, :location => #susbscriber }
else
format.js { render :json => #susbcriber.errors, :status => :unprocessable_entity }
end
end
end
Also, you shouldn't have to do the unless Subscriber.find_by_email(params[:email]) in your controller. You should just add validates_uniqueness_of :email to the Subscriber model.
you want something like render :layout => !request.xhr? in your controller, this will prevent the layout if the request is ajax
I'm trying to create a JSONP API for my Rails 3 application. Right now in my controllers, I have a lot of actions which follow this pattern:
# This is from my users_controller.rb, as an example
def index
#users = User.all
respond_with(#users, :callback => params[:callback])
end
While this works as is, I would like to DRY it up by not having to repeat the :callback => params[:callback] in every action's call to respond_with. How can I do this?
Update: One thing I've realized that is ugly about my above code is that the :callback => params[:callback] option will be passed for any response format, not just JSON. The following code is probably more correct:
def index
#users = User.all
respond_with(#users) do |format|
format.json { render :json => #users, :callback => params[:callback]}
end
end
There are a couple ways I've considered to address this problem, but I can't figure out how to make them work:
Override render (perhaps in the application controller) so that it accepts a :jsonp option that automatically includes the :callback => params[:callback] parameter. This way I could change the above code to the following, which is somewhat shorter:
def index
#users = User.all
respond_with(#users) do |format|
format.json { render :jsonp => #users}
end
end
Create a responder that overrides to_json in order to solve my problem. That way I could leave out the block and just call respond_with(#users, :responder => 'MyResponder') to solve the issue. Or perhaps I could include this code in an application responder using plataformatec's responders gem so that respond_with(#users) by itself would be sufficient.
Note that technically, it is incorrect to render JSON with a callback parameter, since you get a JavaScript response (a function call to the JSON-P callback) rather than a JSON result.
So if you have
render :json => my_object, :callback => params[:callback]
and a request for /users?callback=func comes in, Rails would answer
func({…})
with content type application/json, which is incorrect, since the above response is clearly not JSON but JavaScript.
The solution I use is
def respond_with_json(item)
respond_with do |format|
format.json { render :json => item }
format.js { render :json => item, :callback => params[:callback] }
end
end
which responds correctly with or without callback. Applying this to the aforementioned solution, we get:
def custom_respond_with(*resources, &block)
options = resources.extract_options!
if params[:callback]
old_block = block
block = lambda do |format|
old_block.call(format) if block_given?
format.js { render :json => resources[0], :callback => params[:callback] }
end
end
respond_with(*(resources << options), &block)
end
Also note the correction to resources[0], otherwise you end up wrapping resources in an extra array as a result of the splat operator.
THere's a gem that can do this to: rack-jsonp-middleware.
The setup instructions are pretty scant on the site, but I did create a little Rails project that uses it - which you can take a look at the commits and see what I did to get the middleware up and running.
https://github.com/rwilcox/rack_jsonp_example
This is bit 'low-tech' compared to the reponder solution, but what about just creating a private method in your appliation_controller.rb to handle this. The params variable will be available to it and you could pass the #users object to it.
#application_controller.rb
private
def jsonp(my_object)
render :json => my_object, :callback => params[:callback]
end
#controller
def index
#users = User.all
respond_with(#users) do |format|
format.json { jsonp(#users)}
end
end
Thanks to samuelkadolph for helping me in the #rubyonrails IRC channel today. He provided a solution in this gist, copied below for convenience:
def custom_respond_with(*resources, &block)
options = resources.extract_options!
if options[:callback]
old_block = block
block = lambda do |format|
old_block.call(format) if block_given?
format.json { render :json => [] }
end
end
respond_with(*(resources << options), &block)
end
I haven't tried this in my application yet, but I can see that it should work. He also confirmed that I could similarly override the respond_with method itself simply by changing the name of this method and changing the last line of the definition to super(*(resources << options), &block).
I think this will work for me. However, I'm still interested in knowing how to write a custom responder to do the job. (It would be a more elegant solution, IMHO.)
Update: I tried this in my application and it works with some minor changes. Here is the version I'm using now in the private section of my ApplicationController, designed to automatically provide the :callback => params[:callback] option to JSON requests:
def custom_respond_with(*resources, &block)
options = resources.extract_options!
if params[:callback]
old_block = block
block = lambda do |format|
old_block.call(format) if block_given?
format.json { render :json => resources, :callback => params[:callback] }
end
end
respond_with(*(resources << options), &block)
end
Note that I had to change if options[:callback] to if params[:callback] in order to get it working.
You can also check out this answer. basically you can create a "default" respond_to for your controller so you can just make your all your actions default to responding to json.
was that what you were asking?