I'm rather new to the Ruby ecosystem and am drowning. I guess I was spoiled by the easy intellisense of Visual Studio w C#. Anyway, I'm using Ruby 1.9.3, Rails 3.2.13, and Devise 3.0.3 on Ubuntu.
I can login to this website, via a browser on a PC. But when I attempt to do it from our Phonegap mobile-app, I get this error:
NameError: 'undefined local variable or method 'build_resource' for #
..
Here is the code within sessions_controller.rb:
class SessionsController < Devise::SessionsController
def create
respond_to do |format|
format.html {
super
}
format.json {
build_resource # <-This line is evidently producing an error!
user = User.find_for_database_authentication(:email => params[:user][:email])
return invalid_login_attempt unless resource
return invalid_login_attempt unless user
..
Evidently, it is the line that contains build_resource, that is producing the error. I'd appreciate any help to point me where to go. What does that line even do? Is that a method-call? How does one discover what that calls?
If you go here you see the devise registrations_controller.
It has the build_resource method, that you are calling in you sessions_controller
# Build a devise resource passing in the session. Useful to move
# temporary session data to the newly created user.
def build_resource(hash=nil)
self.resource = resource_class.new_with_session(hash || {}, session)
end
The problem is that it is protected ( under the line that says protected ) That means that the build_resource method can only be called from the devise registrations_controller.
The reason it works with the browser it that the create action in you sessions_controller calls
super
This means that it calls the create action from the devise sessions_controller, which your sessions_controller inherits from -
#devise/sessions_controller
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_flashing_format?
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
end
This gist shows how to login users trough a json api.
It uses this include
include Devise::Controllers::InternalHelpers
in the sessions_controller. I think this makes it possible to use the build_resource
method.
Good luck!
Edit
def create
respond_to do |format|
# when you log into the application through a web browser you go to the format.html option
# Thus you're not calling the build_resource method
format.html {
super
}
# So, lets try to sign in without the build_resource
# I am not really sure what you can do, but try this
format.json {
resource = User.find_for_database_authentication(:login=>params[:user_login][:login])
return invalid_login_attempt unless resource
if resource.valid_password?(params[:user_login][:password])
sign_in("user", resource)
render :json=> {:success=>true, :auth_token=>resource.authentication_token, :login=>resource.login, :email=>resource.email}
return
end
invalid_login_attempt
end
# build_resource # <-This line is evidently producing an error!
# user = User.find_for_database_authentication(:email => params[:user][:email])
# return invalid_login_attempt unless resource
# return invalid_login_attempt unless user