Rails3/Devise: undefined method new_application_user_session_path - ruby-on-rails

Following the README documentation, I installed Devise into an existing Rails 3 application. However, it doesn't seem to work. When I try to access one of my controllers that have before_filter :authenticate_application_user!, I get the following error message:
undefined method 'new_application_user_session_path' for #<Devise::FailureApp::0x60aldc0>
I have no idea why. I've checked numerous to see if I followed the installation guide correctly, to no avail. So I'm wondering if anyone cold help me out.
Here is my routes.rb
AwesomeApp::Application.routes.draw do
devise_for :application_users
root :to => "home#index"
scope "admin" do
resources :application_users, :path => "users"
end
end
Here is my Gemfile:
source 'http://rubygems.org'
gem 'rails', '3.0.0'
gem 'ruby-oci8'
gem 'activerecord-oracle_enhanced-adapter'
gem 'warbler'
gem 'devise', '1.1.3'
group :development, :test do
gem 'factory_girl_rails'
gem 'forgery'
end
Here is my migration file for updating my existing database schema:
class DeviseCreateApplicationUsers < ActiveRecord::Migration
def self.up
change_table(:application_users) do |t|
t.rememberable
t.trackable
end
end
def self.down
change_table(:application_users) do |t|
t.remove :rememberable, :trackable
end
end
end
NOTE: In case anyone is wondering, I will be authenticating using LDAP. So that's why you don't see t.database_authenticatable
Here is my model application_user.rb:
class ApplicationUser < AbstractModel
devise :rememberable, :trackable, :timeoutable
end
Here is my devise.rb initializer file:
Devise.setup do |config|
config.mailer_sender = "please-change-me#config-initializers-devise.com"
require 'devise/orm/active_record'
config.authentication_keys = [ :user_ldap_id ]
config.stretches = 10
config.encryptor = :bcrypt
config.pepper = "SALT AND PEPPERS HERE, SALT SALT SALT"
end
NOTE: Because I will be authenticating against LDAP, I am using a different column other than the default email column that Devise defaults to. As a result, I had to install the Devise views (rails g devise:views) and modify the app/views/devise/session/new.html.erb file to use user_ldap_id instead of email.
NOTE: I removed any irrelevant code from these snippets.

The problem was because I did not have the database_authenticable enabled in my model. Without that, no routes will be generated. But because I don't need it, there was no point. However, to resolve this issue, I had to install Devise LDAP Authenticatable and enabled it in my model. Once I did that and restarted the server, the route became accessible.
Take a look at this ticket I created on the Devise Github repo. Someone there was able to walk me through the entire thing. Quite impressed actually at how responsive they were.
https://github.com/plataformatec/devise/issues/issue/614/#comment_517418
Added the following to my Gemfile:
gem 'devise_ldap_authenticatable'
Added the following to my application_users.rb:
devise :ldap_authenticatable

Related

Devise Token Auth installation: default routing settings causing error

From a clean create-repack-app install. I add the following to my Gemfile then run bundle:
gem 'devise_token_auth'
Then I run:
rake db:create
rails g devise_token_auth:install
rake db:migrate
Databases (dev and test) are created and ruby files generated (including an addition to the config/routes.rb file). Trying any rake or rails command does the following right now:
rake routes
rake aborted!
NoMethodError: undefined method `devise' for User (call 'User.connection' to establish a connection):Class
Commenting out the following in the config/routes.rb file:
mount_devise_token_auth_for 'User', at: 'auth'
Removes this error. The code added to the User model doesn't contribute to this error. Do I need to run rails g devise:install also? The documentation doesn't mention anything extra. So I'm not sure what I'm doing wrong.
Add below code to the User model
extend Devise::Models
My User model looks like this.
# frozen_string_literal: true
class User < ActiveRecord::Base
extend Devise::Models
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable, :trackable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
include DeviseTokenAuth::Concerns::User
end
I found my answer from another post: Devise_token_auth conflicts?
Adding the following Devise initializer:
config/devise.rb:
Devise.setup do |config|
# The e-mail address that mail will appear to be sent from
# If absent, mail is sent from "please-change-me-at-config-initializers-devise#example.com"
config.mailer_sender = "support#myapp.com"
# ==> ORM configuration
# Load and configure the ORM. Supports :active_record (default) and
# :mongoid (bson_ext recommended) by default. Other ORMs may be
# available as additional gems.
require 'devise/orm/active_record'
# If using rails-api, you may want to tell devise to not use ActionDispatch::Flash
# middleware b/c rails-api does not include it.
# See: https://stackoverflow.com/q/19600905/806956
config.navigational_formats = [:json]
end
Fixed the problem.

undefined method 'devise' for User

I have been looking to get to grips with devise and its workings and have kind of fallen at the first hurdle. I have looked in a few places but cannot seem to find someone with this error exactly.
So I have created a simple Home controller with an index view and added root 'home#index' and also ensured the default url options are setup in the development.rb file. I then simply typed:
rails generate devise User
This created my user.rb file in models with the following:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Pretty straightforward so far, I have the following Gemfile:
source 'https://rubygems.org'
gem 'rails', '4.0.5'
gem 'sqlite3'
gem 'sass-rails', '~> 4.0.2'
gem 'devise'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'
group :doc do
gem 'sdoc', require: false
end
gem 'bcrypt'
And when I run either rake db:migrate I get the following error:
rake aborted!
NoMethodError: undefined method `devise' for User (call 'User.connection' to establish a connection):Class
/home/jonlee/.rvm/gems/ruby-2.1.1#railstutorial_rails_4_0/gems/activerecord-4.0.5/lib/active_record/dynamic_matchers.rb:22:in `method_missing'
/home/jonlee/Projects/rails/userauth/app/models/user.rb:4:in `<class:User>'
/home/jonlee/Projects/rails/userauth/app/models/user.rb:1:in `<top (required)>'
Im at a loss as to why the User model cannot find the 'devise' method when as far as I can see it is definitely there.
I get similar errors with rake routes, rails server and rails console.
For further info I am using ruby 2.1.1 if that helps?
Add devise to your application Gemfile and install it by running bundle install. After this, you should run the following generator command:
rails generate devise:install
This generator will install an initializer your_application/config/initializers/devise.rb which consists of all the Devise's configuration options.
You missed the above mentioned step which is why the devise configurations are not set and you receive undefined method 'devise' for User error in your model class User.
I ran into a similar issue when I was configuring Devise (Ruby 2.4.1 / Rails 5.1.2). In my case it seems that the following files were not created after I executed: rails generate devise:install for the first time.
create config/initializers/devise.rb
create config/locales/devise.en.yml
Steps that I followed:
1) Comment from your MODEL the following:
#devise :database_authenticatable, :registerable,
#:recoverable, :rememberable, :trackable, :validatable
2) Comment from routes.rb:
#devise_for :sessions
3) Run rails generate devise:install again, you should see that some files are created this time. Hope you it works !
4) Uncomment from 1) & 2)
5) Execute: rake db:migrate
And at this point it should work. Hope it helps someone !
I have the same issue but with other reason. this can also be problem for somebody. Stop rails server
and then type
rails s
to restart it
I've run the generator $ rails generate devise:install but got the same issue.
Anyway it works to me: Add extend Devise::Models to the User models.
In addition to Kirti's answer of running
rails generate devise:install
you may want to rename the devise initializer to
config/initializers/01_devise.rb
because if any other initializer (such as config/initializers/active_admin.rb) runs before devise and touches the ApplicationController, you will get the same error.
And according to
http://guides.rubyonrails.org/configuring.html#using-initializer-files
you control the load order of initializers using file naming.
I had the same issue. The fix was to uncomment:
require 'devise/orm/active_record'
in config/initializers/active_admin.rb.
I deliberately commented it out earlier because documentation says: "Supports :active_record (default)".
Extend Devise::Model
class User < ActiveRecord::Base
extend Devise::Models
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
include DeviseTokenAuth::Concerns::User
end
Reference: https://dev.to/risafj/guide-to-devisetokenauth-simple-authentication-in-rails-api-pfj
So I just had this same error crop up when I did:
rails g controller client/timesheets
It turned out that the problem was with the generated helper:
app/helpers/client/timesheet_helper.rb:
module Client::TimesheetHelper
end
Client is a model that uses Single Table Inheritance off of the User model. Something was getting very mixed up her, what with Client being a Model (class) and a module, and it results in this cryptic error message.
YMMV.
I got the same error when I installed Devise and Mongoid, but forgot to change the orm from active_record to mongoid in config/initializers/devise.rb
Should be:
require 'devise/orm/mongoid'
I had to stop the Spring preloader process:
spring stop
Now works as expected
I had this problem because executed rails g devise user before to rails g devise:install
I solved this, removing line devise_for :users at config/routes.rb
and deleting db/migrate/xxxxxx_add_devise_to_users.rb
now run
rails g devise:install
rails g devise user
I run into this issue as well, solved it by :
Steps:
Comment out all references to devise most importantly in the routes.rb and
user.rb model
run rails g devise:install and be sure you follow the suggested steps
in the guide on screen.
Go on and uncomment references to devise in routes.rb and user.rb
run rake db:migrate
And you good to go!
comment your app/model/user.rb and also comment devise route in config/routes.rb
`rails generate devise:install`
then run
`rails db:migrate`
then uncomment all done before
this method work for me on rails 7.0.0.4
Also ran into the same problem.
For your case, you should first of all stop the server, and restart it. This should work out!
For more insight, you should also consier visiting this site; https://edgeguides.rubyonrails.org/routing.html
I got the same issue now with a lagacy system. The problem was caused by a commented line (remained there at migration from Rails 4 to 5) in the header of config/routes.rb:
#V2p0::Application.routes.draw do
devise_for :users
Rails.application.routes.draw do
devise_for :users
The devise initialization script inserted devise_for also below the commented line. After removing it the problem disappeared.
Comment out:-
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
in user.rb Model. This worked for me

Rails Gem::LoadError in UsersController#new

New to Ruby on Rails and having a problem when following Michael Hartl's tutorial.I'm using Rails 3.2.2 with Ruby 1.9.3. The issue looks very similar to another question that was raised but was unanswered:
Rails Error NoMethodError in UsersController#show error
I get the following error when attempting to add a new user via /signup
Gem::LoadError in UsersController#new
bcrypt-ruby is not part of the bundle. Add it to Gemfile.
Reloading the page gives the error:
NoMethodError in UsersController#new
undefined method `key?' for nil:NilClass
The problem seems to be related to the inclusion of the bcrypt-ruby gem, and the usage of the has_secure_password method in user.rb . Removing the call to has_secure_password in user.rb gets rid of the error and it goes to the signup page successfully.
user.rb:
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# email :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# password_digest :string(255)
#
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
validates :name, presence: true, length: { maximum: 50 }
valid_email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: valid_email_regex },
uniqueness: { case_sensitive: false }
validates :password, length: { minimum: 6}
end
users_controller.rb:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:success] = "Welcome!"
redirect_to #user
else
render 'new'
end
end
end
However, I cant find anything wrong with the inclusion of the bcrypt-ruby gem. In the Gemfile I have:
gem 'bcrypt-ruby', '3.0.1'
and the gem has also been generated in Gemfile.lock :
DEPENDENCIES
annotate (~> 2.4.1.beta)
bcrypt-ruby (= 3.0.1)
I've also added password_digest to the database via migration:
class AddPasswordDigestToUsers < ActiveRecord::Migration
def change
add_column :users, :password_digest, :string
end
end
Any ideas ?
I'm going through the same tutorial and encountered the exact same problem.
My solution was to restart the web server. After installing the gem, I think the web server needs to be restarted so it is loaded.
Justin
Did you tried the 'bundle update' command, usually the bundler will take care of gems if you specified in the Gemfile. If you want to check the gem dependency please check http://rubygems.org/gems.
And if you are using windows(I know its strange- but some of our app works in windows only) there is some tricks to install bcrypt
Steps to install bcrypt.
1 Download Devkit and extract
you can download it from here http://rubyinstaller.org/downloads/
2 Place devkit it your jruby folder (in my case C:\applications\jruby\devkit)
3 You need to install ruby as well either 1.8.7 or 1.9(some times needs a system restart)
4 CD into devkit directory
5 Run ruby dk.rb init
6 Open config.yml and make sure that both your jruby installtion is listed. If not, ADD them. Save and close config.yml after you're done.
example:- C:/applications/jruby
7 Run ruby dk.rb install
8 jruby -S gem install bcrypt-ruby
Restarting the web server fixed it for me (had spork running in the background to speed up the running of the tests)

How to create Devise extension?

I need to create reusable Devise extension. This is my first experience of creating gems. So, according sources of other Devise extensions, i've started with creating file devise_sms_authenticatable.rb in 'lib' folder with following code:
# encoding: utf-8
unless defined?(Devise)
require 'devise'
end
Devise.add_module :sms_authenticatable, :model => 'devise_sms_authenticatable/model'
Also, i've created folder devise_sms_authenticatable in the 'lib' folder, and added model.rb with code:
# encoding: utf-8
module Devise
module Models
module SmsAuthenticatable
# ...
end
end
end
After all i've added my new extension to the User model.
class User << ActiveRecord::Base
devise ..., :sms_authenticatable
end
But application falls with error uninitialized constant Devise::Models::SmsAuthenticatable (NameError). What i'm doing wrong?
If you're putting the SmsAuthenticatable module already on Devise::Models, there is no need to add it through add_module, though you may need to require it on config/initializers/devise (if you're writing a gem, you may avoid this, since you will not touch devise.rb on initializers).
You can also write its code without Devise::Models in your gem lib directory and only add this line
Devise.add_module :sms_authenticatable, :model => 'sms_authenticatable'
And Devise should add the module.

Ruby on Rails 3: Devise::LdapAdapter.get_ldap_param undefined method error

I am running:
Ruby 1.9.3p0,
Rails 3.1.1,
Devise 1.4.9,
Devise_ldap_authenticatable 0.4.10
I am using Devise to authenticate my Rails application via an ldap server. I am using username instead of email to authenticate, so naturally the email field in my table is blank.
To query the ldap for email, the official way is to add this code in the user model:
before_save :get_ldap_email
def get_ldap_email
self.email = Devise::LdapAdapter.get_ldap_param(self.username,"mail")
end
This code fails, without attempting to do anything with the ldap, with this:
undefined method `mail' for nil:NilClass
It refers to the line inside the method definition. The log output is no more helpful:
Started POST "/users/sign_in" for 10.50.1.96 at 2011-11-15 11:18:16 -0800
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"<hidden>=", "user"=>{"username"=>"<hidden>", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."username" = '<hidden>' LIMIT 1
LDAP: LDAP dn lookup: uid=<hidden>
LDAP: LDAP search for login: uid=<hidden>
LDAP: Authorizing user <hidden>
LDAP: LDAP dn lookup: uid=<hidden>
LDAP: LDAP search for login: <hidden>
Completed 500 Internal Server Error in 251ms
NoMethodError (undefined method `mail' for nil:NilClass):
app/models/user.rb:14:in `get_ldap_email'
All lines previous to the 500 error are normal LDAP successful authentication that are unrelated to the the email query.
I started learning Ruby, Rails, and Devise just last week, so I'm not sure what files would be the most telling, but here is my user.rb model and gemfile:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :ldap_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
before_save :get_ldap_email
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :username, :password, :password_confirmation, :remember_me
def get_ldap_email
self.email = Devise::LdapAdapter.get_ldap_param(self.username,"mail")
end
end
And the gemfile:
source 'http://rubygems.org'
gem 'rails', '3.1.1'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'sqlite3'
<... unrelated ...>
gem 'therubyracer', :platforms => :ruby
gem "devise"
gem "devise_ldap_authenticatable"
I have tried restarting the server, and have done a bundle install since the last GemFile update. My configuration has ldap_create_user = true and username is the correct field name in users. Is there an error in that method? Could there be a version incompatibility? I'm not really sure what else to check, and rails is giving me nothing beginner-friendly to go on. I would love some help with this.
I'm also having this problem - my current temporary solution is to fetch the data myself using Net::LDAP instead of the ldap_authenticatable classes. The more permanent solution would, of course, be to patch ldap_authenticatable, which I may try to do next.
The issue (at least for me) was this: After poring through the ldap_authenticatable code (namely ldap_adapter.rb) I discovered that the get_ldap_param method is not authenticating with the server when trying to fetch the params unless admin_user and admin_password are specified in ldap.yml. So, if your LDAP server allows anonymous reading of data, then get_ldap_param will work as advertised. On OpenLDAP (which is what I use for local testing), anonymous read access is set with the "access to" property in slapd.conf:
access to *
by anonymous auth
But, my corporate LDAP does not allow that.
The Net::LDAP instance in ldap_authenticatable needs to be created with auth parameters when being used for parameter fetching, but it's not. No auth parameters are given, so no results are returned.
So, temporarily, I have the following code in my User model, calling get_ldap_data as a before_save filter:
def has_ldap_data?
[self.email, self.first_name, self.last_name].none? {|v| v.nil?}
end
def get_ldap_data
return true if has_ldap_data? or self.password.nil?
ldap = create_ldap
ldap.search(
:base => ldap.base,
:attributes => ['cn', 'sn', 'givenname', 'mail'],
:filter => Net::LDAP::Filter.eq('cn', self.username),
:return_result => true) do |entry|
self.email = entry.mail.first
self.first_name = entry.givenname.first
self.last_name = entry.sn.first
end
has_ldap_data?
end
def create_ldap(password = nil)
ldap_config = ldap_config = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#{Rails.root}/config/ldap.yml")).result)[Rails.env]
ldap_options = {
:host => ldap_config["host"],
:port => ldap_config["port"],
:base => ldap_config["base"],
:auth => {
:method => :simple,
:username => "cn=#{self.username},#{ldap_config['base']}",
:password => password || self.password
}
}
ldap_config["ssl"] = :simple_tls if ldap_config["ssl"] === true
ldap_options[:encryption] = ldap_config["ssl"].to_sym if ldap_config["ssl"]
Net::LDAP.new(ldap_options)
end
Modify per your particular needs. It's not ideal, but works for now until forking/patching ldap_authenticatable to account for this use case.
So here's the problem and a potential solution.
ldap_get_param assumes that anonymous read access to the LDAP server is allowed, and thus tried to bind and read with {:method => :anonymous}. If your server does not allow anonymous searches, and eg. Active Directory does not by default, then your call will fail with the obscure error message above, which is really trying to say "no matching results".
Unfortunately, devise_ldap_authenticable does not allow you to require authentication for read operations, so I went and forked a copy that does. To use it instead, slot this into your Gemfile instead of the original:
gem 'devise_ldap_authenticatable', :git => 'https://github.com/jpatokal/devise_ldap_authenticatable.git'
And then call get_ldap_param like this:
Devise::LdapAdapter.get_ldap_param(self.login,"mail",self.password)
Note the 3rd parameter there. I've also submitted this as a pull request to master, and you can track the issue here: https://github.com/cschiewek/devise_ldap_authenticatable/issues/94
I'm afraid I don't got the answer for you, but I can tell you that I'm getting the same exact error as you.
I've done a couple of posts here at StackOverflow but haven't gotten any answers. Everything works fine for me until I try to pull extra attributes and :before_save. I've traced my eDir server with ndstrace and it says the question it gets is empty?! So it seems that my selected attribute is not passed down to the ldap server.
Probably this is related to the version you are using.
Inspecting the git repository of the project, I see that the method get_ldap_param has been introduced with version 0.4.7.
Check that you have no constraints on the version of the devise_ldap_authenticatable gem in your Gemfile, and remove them in the case, then run
$ bundle update devise_ldap_authenticatable
it should update your gem to version 0.6.0 (with devise 2.0.1), and the method is present and working.
You could also specify a minimum version in the Gemfile, if you think it is the case:
gem 'devise_ldap_authenticatable', '~> 0.4.7'

Resources