Devise find_for_authentication not firing with multiple authentication keys - ruby-on-rails

I have two devise models: User and Member
As such, I'm specifying authentication keys on the models themselves instead of in the Devise initializer.
Member.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :authentication_keys => [:email, :subdomain]
I also override
def self.find_for_authentication(conditions={})
debugger
conditions[:account_id] = Account.find_by_subdomain(conditions.delete(:subdomain)).id
super(conditions)
end
Unfortunately, when authentication_keys has multiple keys, my find_for_authentication method doesn't appear to be firing. Works fine when I specify just one key. Any thoughts?

subdomain should have been a request_key since it's part of the request.
request_keys => [:subdomain]

Related

Devise, where to add a model

I want to add a timeoutable model to devise after my initial configuration.
I enabled the config/initializers/devise.rb:
config.timeout_in = 30.minute
But where do I actually add the devise :timeoutable model?
After you install devise you need to configure model using built in generator
rails generate devise MODEL
example rails generate devise User. See this section
https://github.com/plataformatec/devise#user-content-getting-started
Once you have that inside app/models/user.rb you can add desired modules
class User < ApplicationRecord
devise :timeoutable, :database_authenticatable, :registerable,:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable
end
Hope it helps

Moving devise model to React.rb public directory calls method missing

I'm trying to use Devise with React.rb, so I thought I'll move my user model to the public directory to be able to edit it through React, however I get this error:
ActionView::Template::Error(User.devise(database_authenticatable,registerable,recoverable,rememberable,trackable,validatable) (called class method missing)):
1: <%= react_component #component_name, #render_params, { prerender: !params[:no_prerender] } %>
You probably have some devise specific macros in your user model.
for example if you user model looks like this:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# etc...
end
then you will need to insure the devise call only runs on the server like this:
class User < ActiveRecord::Base
unless RUBY_ENGINE=='opal'
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
# etc...
end
Reactive-Record stubs and proxies all the standard active-record macros like scope, and belongs_to on the client. However it doesn't know what the devise method means, so wrapping it in unless RUBY_ENGINE=='opal will prevent this from being called on the client.
FYI I added an issue https://github.com/catprintlabs/reactive-record/issues/17 to reactive-record to cover this...

devise signin using username or email

Below is my model. Can anyone explain me the purpose of attr_accessor: signin here ?. I have seen from some posts here stating that attr_accessor creates getter and setters.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessor :signin
end
In the devise.rb file, i have something like this.
config.authentication_keys = [ :signin ]
Questions:
Can anyone explain me the purpose of attr_accessor: signin here ?.
What does this config.authentication_keys = [ :signin ] lead to in device.rb file?.
This option enables you to pick authentication key. You are telling devise to use accessor signin (that you declared above).
Default one used is email:
config.authentication_keys = [ :email ]

Get variable from another table in ROR models

I am trying to get a user who has not filled out their profile to redirect to the edit page.
I have two tables - Users (Devise handles) and Profiles.
Profiles has a row called profile_complete
In my user model I am trying to define a method called profile_complete which takes the boolean of profiles_complete and passes it back.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
has_many :profiles, :dependent => :destroy
def profile_complete?
self.profile.profile_complete == true
end
end
But cannot seem to figure out what the line in the profile_complete method is. I have got the other bits working in the correct place but cant get this variable across Any help? Cheers :)
def profile_complete?
self.attributes.values.include?(nil) ? false : true
end

Disabling validations when reseting passwords in Devise/Warden

I have a user model as follows:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :invitable,
:recoverable, :rememberable, :trackable, :validatable,
:token_authenticatable, :omniauthable
validates_presence_of :nickname, :unless => :skip_nickname_requirement
end
I have a number of user records in the database with a nil nickname - those individuals were imported from another system and I don't actually have their nickname. Those users are invited to set their passwords via the lost passwords link like http://example.com/users/password/edit?reset_password_token=iAYeQRwWrt8geC8eEXR4, and then when they log in, add their personal details such as nickname, etc.
The problem is that when you go to that reset password you're prompted to enter your password (and again for confirmation). When you submit, validation fails because the nickname is nil.
How do I disable the nickname validation when reseting your password? I don't want to add the nickname textfield on the password reset form.
Thanks in advance for your thoughts!
I don't know if simple validates_presence_of :nickname, allow_blank: true would solve your problem, because you may want it to be blank only for those imported users. Therefore, other way would be to use custom validations.
# app/models/user.rb
class NicknameValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors[attribute] << "validation failed" unless :skip_nickname_requirement?(value)
end
private
def skip_nickname_requirement?(values)
# imported_from_legacy_system? would need to be implemented
value.present? || self.imported_from_legacy_system?
end
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :invitable,
:recoverable, :rememberable, :trackable, :validatable,
:token_authenticatable, :omniauthable
validates :nickname, :nickname => true
end

Resources