I'm using devise in my Admin model like so:
class Admin < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Functionally, this is working fine. But I want to have specs for my Admin class, so I start to write a spec...
require 'spec_helper'
require 'admin'
describe Admin do
it 'mumblemumble' do ... end
end
...and then when I go to run the spec, it blows up:
active_record/dynamic_matchers.rb:22:in `method_missing': undefined method `devise' for Admin(Table doesn't exist):Class (NoMethodError)
How do I require Devise so that it's available in my spec? It seems like I should be able to
require 'devise'
in either my spec or my model (preferably my model), but this doesn't fix the issue or change my stack trace. How do I require Devise so that my model has the helper method available? I'm poking around the Devise gem but I'm not finding any clues.
How are you running these? RSpec directly? Or bundle exec rake spec?
There's this in your error: for Admin(Table doesn't exist) which makes me wonder if you have a database yet. The rake task should take care of setting up your world for you.
If that doesn't help, post your spec_helper.rb contents too.
Here's a basic Admin model I have:
class Admin < ActiveRecord::Base
devise :database_authenticatable, :recoverable, :rememberable,
:trackable, :validatable
end
And a basic spec:
require 'spec_helper'
describe Admin do
it { should validate_uniqueness_of(:email) }
end
Works great with vanilla generated rails app and generated devise setup.
This error
undefined method `devise' for Admin(Table doesn't exist):Class (NoMethodError)
seems to be that you don't have the table in the db? Did you migrate the rake file?
Yes it seems your test database does not have the admins table.
Try this:
bundle exec rake db:migrate db:test:prepare
db:migrate migrates your development database, if there are any pending migrations and db:test:prepare clones your test database according to the development one.
Got it. I run specs with an in-memory instance of sqlite3, so all the db:test:prepare doesn't apply to me. In addition to requiring Devise, it must also be setup/configured.
So in /spec/support/devise.rb:
require 'devise'
Devise.setup do |config|
require 'devise/orm/active_record'
end
And then in spec_helper.rb:
Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
Related
The following errors appears when I try to run rails console in production. (In development mode it works as expected)
bin$ RAILS_ENV=production ./rails c
/home/ubuntu/app/shared/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.7/lib/active_support/dependencies.rb:509:in `load_missing_constant': Circular dependency detected while autoloading constant AdminUser (RuntimeError)
My AdminUser contains the following:
class AdminUser < ApplicationRecord
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
end
It'll be more helpful if you can post code for AdminUser
check your code (AdminUser) for circular references like
1: callback triggering the same callback (update self after update)
2: method calling the same method
Pluralizing all the controllers under /admin fixed this issue
https://github.com/activeadmin/activeadmin/issues/2334#issuecomment-42626409
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.
I decided to try using simplecov gem, and I think it's a cool tool, but I have one problem:
I have a model User, and I have user_spec.rb which contains test cases, but simplecov shows 0% coverage of this model. And it shows 100% coverage for other models, which is true. I don't understand what's the issue with the User model.
class User < ActiveRecord::Base
extend Enumerize
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
STATUS_ACTIVE = :active
STATUS_BANNED = :banned
enumerize :status, in: [STATUS_ACTIVE, STATUS_BANNED], default: STATUS_ACTIVE
with_options inverse_of: :user, dependent: :destroy do
has_one :profile
has_many :articles
end
before_create :build_default_profile
private
def build_default_profile
build_profile
end
end
user_spec.rb
require 'rails_helper'
RSpec.describe User, type: :model do
describe '#validations' do
it { should have_one(:profile).dependent(:destroy) }
it { should validate_presence_of(:email) }
it { should validate_presence_of(:password) }
it { should validate_confirmation_of(:password) }
it { should enumerize(:status).in(User::STATUS_ACTIVE, User::STATUS_BANNED).with_default(User::STATUS_ACTIVE) }
#TODO other devise validations
end
describe '#callbacks' do
it 'creates profile after_create' do
user = build(:user)
expect(user.profile).to be_nil
user.save
expect(user.profile).to be_a(Profile)
end
it 'must not create profile after update' do
user = create(:user)
profile = user.profile
user.email = Faker::Internet.email
user.save
expect(profile.id).to eq(Profile.find_by(user_id: user.id).id)
end
end
end
coverage
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
app/models/user.rb 0.0 % 28 28 0 28 0.0
app/models/admin.rb 100.0 % 3 1 1 0 1.0
app/models/article.rb 100.0 % 32 19 19 0 5.8
app/models/profile.rb 100.0 % 13 6 6 0 1.0
Make sure that you are starting SimpleCov correctly. In your case,
Load and launch SimpleCov at the very top of your rails_helper.rb
See more: https://github.com/colszowka/simplecov#getting-started
It happens with me only when I use spring, actually when I use rspec binstub generated by spring-commands-rspec gem. Try to stop spring with command spring stop and run specs again with rspec spec.
I have a similar issue. I have the current simplecov 0.17.1.
I'm using Rails 6 with the default setup (Minitest and Spring, no rspec), I run my tests with rails test.
I have try all the other answers without success.
simplecov may be buggy: https://github.com/colszowka/simplecov/issues/671
I'm trying alternative like fastcov
edit1
fastcov seems to be a ligthen copy of simplecov, not mature at all. It's not released yet! Is their any alternative to simplecov?!
edit2
I manage to make it work by adding to the top of bin/rails
#!/usr/bin/env ruby
if ENV['RAILS_ENV'] == 'test'
require 'simplecov'
SimpleCov.start 'rails'
puts "required simplecov"
end
# ...
AND in test_helper.rb, I set parallelize(workers: 1)
# test/test_helper.rb
require 'simplecov'
SimpleCov.start 'rails'
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
class ActiveSupport::TestCase
parallelize(workers: 1)
fixtures :all
end
I run tests with the command RAILS_ENV=test rails test
You have to create an initilizer like this:
config/initializers/simplecov.rb
if ENV['RAILS_ENV'] == 'test'
require 'simplecov'
SimpleCov.start 'rails'
puts "required simplecov"
end
I had the same problem and just found the answer here: https://github.com/colszowka/simplecov/issues/82
The require should be happening before loading anything else. In my case I had:
require simplecov
SimpleCov.start 'rails'
after:
require File.expand_path('../../config/environment', __FILE__)
which probably made the devise modules not being loaded. As soon as I moved the "require simplecov" and "simplecov.start" to the very beginning of rails_helper, it worked as expected.
The metric that simplecov displays is the number of lines that get called in the process of running test cases. For example if I had:
class Test
def method
'Response'
end
end
RSpec.describe Test, type: :model do
context '#method' do
let(:test) { Test.new }
it 'returns response' do
expect(test.method).to eq('Response')
end
end
end
simplecov will show 100% coverage because it is hitting every single line in the Test class when I run my specs. In the case of your user class, your specs don't actually invoke any lines in the user class because you don't have any relevant lines (it isn't considering your private method to be relevant).
I wouldn't worry about the 0% coverage for your user model as the tests you have seem pretty comprehensive.
I was seeing the same issue, and I think it has something to do with Spring rspec binstubs. I'm using the spring-commands-rspec gem and have a binstub for rspec in bin/spring. After creating that binstub, my Simplecov test coverage calculations went down by 10% and showed that my User model had 0% coverage. When I deleted (or renaming works too) the bin/spring script and re-ran rspec, my coverage was back up.
Are you using spring-commands-rspec or any other Spring binstubs to run your tests? I'll post more once I figure out if there's a workaround.
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
I have been working on this issue for hours now and haven't seemed to find anything exactly like this on StackOverflow.
C:\Sites\isawyou>rake db:migrate
rake aborted!
User does not respond to 'devise' method. This usually means you haven't loaded
your ORM file or it's being loaded too late. To fix it, be sure to require 'devi
se/orm/YOUR_ORM' inside 'config/initializers/devise.rb' or before your applicati
on definition in 'config/application.rb'
C:/Sites/isawyou/config/routes.rb:2:in `block in <top (required)>'
C:/Sites/isawyou/config/routes.rb:1:in `<top (required)>'
C:2:in `rescue in execute_if_updated'
C:in `execute_if_updated'
C:/Sites/isawyou/config/environment.rb:5:in `<top (required)>'
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
Issue: Everytime I try to migrate I get this error. However, I do not have a devise.rb file installed so am not sure how to fix this..
Attempts to solve: tried this answer however that didn't let me populate the correct rake routes I needed (ie: new user sessions, create new user, etc..)
Tried redoing the order of commands (as shown below).. But that didn't work either.. I always get stuck at the "rake db:migrate" portion..
$ rails d devise User
$ rails generate devise:install (you may have to override previous files)
$ rails generate devise User
$ rake db:drop
$ rake db:create
$ rake db:migrate
$ rake routes
Thank you in advance if you know the fix!!
It looks like you have devise generator previously run unsuccessfully. Backtrace gives a clue that error happens within config/routes.rb line 2. I guess there is a following line of code, setting up devise routes
devise_for :users
But your users model doesn't have devise modules setup. There should be something like
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :timeoutable and :omniauthable
devise :database_authenticatable, :rememberable, :trackable, :validatable
If this line is present it means that devise is improperly installed.
Also there is a chance that you have another class or module "User" within ActiveSupport::Dependencies autoloader paths and when devise_for :users line requires User class this class/module loaded first, whereas your real User module is not loaded. The "invalid" user module/class is not ActiveRecord descendant, so devise AR hook is not installed to it, so it doesn't have #devise method. So make sure you don't have any other classes/modules named User