Ruby on rails User registration using rest API call and Devise - ruby-on-rails

Can anyone guide me how to register a user from mobile device (rest API) in ruby on rails. I'm using Devise with Rails 3.0.
it is giving me this following error
NameError in Devise::CustomRegistrationsController#create

I've override the functionality of devise registration controller with the following.
def create
respond_to do |format|
format.html {
super
}
format.json {
build_resource
if resource.save
render :status => 200, :json => resource
else
render :json => resource.errors, :status => :unprocessable_entity
end
}
end
end
this solved the problem and I've added
skip_before_filter :verify_authenticity_token, :only => :create
to avoid authenticity check.

Wouldn't it be easier to make views for mobile than make an app on android/iOS? If you need API, then go with POST requests at /users/sign_up (and similar), for example,
browse localhost:3000/users/sign_up and change form's action parameter to action="/users.json", then click submit and you will receive the API's response, for me (on vanilla setup):
{"email":["has already been taken"],"password":["doesn't match confirmation","is too short (minimum is 6 characters)"]}
This way you can debug API (which follows standard conventions) with your browser. Notice that only :format parameter changes on rails routes (you can choose .json or .xml for APIs response)
POST info sent by my browser:
"utf8=✓&authenticity_token=n5vXMnlzrXefnKQEV4SmVM8cFdHDCUxMYWEBMHp9fDw%3D&user[email]=asd%40fasd.org&user[password]=321&user[password_confirmation]=1233&commit=Sign+up"

Related

Rails error: No HTTP_REFERER was set in the request to this action

I am developing a new rails app. but found a error:
ActionController::RedirectBackError in UsersController#show
No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].
my code:
rescue_from CanCan::AccessDenied do |exception|
redirect_to :back
end
I have some question for this error:
what is HTTP_REFERER?
why redirect to back will trigger this error?
Anyone has good idea?
what is HTTP_REFERER?
The HTTP referer is an HTTP header field that identifies the address of the webpage (i.e. the URI or IRI) that linked to the resource being requested. This is set by ActionController::Request object.
why redirect to back will trigger this error?
This usually happens when request.env["HTTP_REFERER"] is not set. (I also wonder to know in which case it is set and not set)
You could refer this answer to fix your issue.
(OR) I would highly prefer to define a custom page for access denied and redirect to it instead of redirecting :back (which I think bad idea)
For example from cancan gem docs,
rescue_from CanCan::AccessDenied do |exception|
render :file => "#{Rails.root}/public/403.html", :status => 403, :layout => false
## to avoid deprecation warnings with Rails 3.2.x (and incidentally using Ruby 1.9.3 hash syntax)
## this render call should be:
# render file: "#{Rails.root}/public/403", formats: [:html], status: 403, layout: false
end
Hope this helps!

Staging subdomains when application already has subdomains

My current Rails application has the following subdomains:
ui.myapp.com
api.myapp.com
I want to set up a staging environment, and I am wondering what is the best approach in order to set the domains.
Usually, I would do:
staging.myapp.com
But then, how do I access the UI/API sites?
Is it 'ok' to do:
ui.staging.myapp.com
api.staging.myapp.com
?
Assumption: The output from API call is expected in JSON format.
It will not be advisable to use separate subdomain for functionality like api.staging.myapp.com. You can always use the same url for web application and API
Better way would be to use same controller-action from Rails application but instead to return JSON output hash.
For example to get the users, you will have some code in users_controller.rb as
class UsersController < ApplicationController
def index
#users = User.all
respond_to do |format|
format.html do
render :index
end
format.json do
render :json => {:users => #users}
end
end
end
end
Now here if the request is html it will render the html page else it will return the json response.
staging.myapp.com/users will get you the html page of web application displaying users collection and that of staging.myapp.com/users.json will provide you the json response hash of users collection.
So, you will not need different subdomain to distinguish the api and normal site. But using format of request you can distinguish the functionality.
I hope this answers your question. If you still have any query feel free to ask.

Creating web APIs with Rails

Trying to implement API calls. What goes in the controller? I think I should create API an API view. Should I use a one of the API gems?
I'm trying to use my first app to write to the database. My 2nd App will use a web API to GET/POST from first app's uri for fields that would share same data.
Take a look at rabl gem it will assist you to generate JSON views using your current controllers, From this you can get the idea of how JSON APIs work and proceed to namespacing your controllers and routes for your API. For http requests between your two apps, you can use either httparty or typhoeus gems
I have done several Api's in RoR, and these are the steps I usually take:
Create a restfull Api:
I usually create a controller for the api, lets call it ApiController, all the requests i do on my app go through that controller
Authenticate the api controller:
for the sake of simplicity here is a non secure way to authenticate the users who use your api:
class ApiController < ApplicationController
before_filter :apiauth
private
def apiauth
if request.headers["ApiAuth"]!='IguD7ITC203'
raise "error"
end
end
end
create some mothods and responses for your api:
here is a simple method you can implement on the controller:
def successOrder
#order=Order.find_by_id(params['id'])
if #order
#order.status=params['status']
if #order.save
render :json => {:status => "true", :order => {:id => #order.id, :status => #order.status}}
else
render :json => {:status =>"false", :errors => #order.errors.full_messages }
end
else
render :json => {:status => "false", :errors => ["Invalid Order Id"]}
end
end
update your routes:
sometimes I like to wildcard my routes for my api, like this:
match '/:action', :to => 'api#%{action}', :constraints => lambda {|r| r.subdomain.present? && r.subdomain == 'api'} , :via => [:post]
Finnaly take a look at gems like Jbuilder that can build you awsome responses for your jsons. hope it helps
I recently created an API which served mobile and web application. I used RABL gem templating system and i was able to customize my API views as i wanted. You can use RABL to generate JSON and XML based APIs from any ruby object.

Devise send_reset_password_instructions does not work

I'm adding a function in my controller, the only goal is to trigger the forgot password procedure through API Request.
Here is the reset_password method-
def reset_password
#user = User.find_by_email(params[:email])
#user.send_reset_password_instructions
respond_to do |format|
format.xml { render :xml => user_api_ressource(#user, :xml)}
format.json { render :json => user_api_ressource(#user, :json)}
end
end
I'm receiving the mail with the reset password link, it opens the page where I can set a new password but when I submit the form it says that the token is invalid.
I'm using sendgrid to send email. I think it's not a token truncate problem.
I'm running the rails application on Heroku cedar with the latest version of devise.
Any idea ?
I just faced the same issue. In my case, it was because the user was unscoped. It seems like it doesn't the user is not found in that case.
It is in the Devise sources in /lib/devise/models/authenticatable.rb at line 113
recoverable = find_or_initialize_with_error_by(:reset_password_token, reset_password_token)
which do not search unscoped.
I'll fork the repo, let me know if you are interested too.

Retrieve Devise errors from a custom SessionController

I made my own SessionController that extends Devise::SessionsController. That way it can respond to HTML, JSON, and XML depending on if the user is in the browser or using a mobile device.
If the format is HTML, I just call super and everything is normal. If it is JSON/XML, I want to be able to display the errors along with the 401 status code if the login did not work. Right now I have:
respond_to do |format|
format.html { super }
if current_user
...
else
format.json { render :json => { :status => 401 } }
end
end
I want to add :errors => ??? to that hash. But how do I get the list of errors from Devise?
Typically, form errors are stored in object.errors (for use in a view). It seems like you might be able to pull the errors out of the resource object, based on the code in the Devise core SessionsController

Resources