EzDevInfo.com

devise interview questions

Top devise frequently asked interview questions

Rails Devise: get object of the currently logged in user?

I've recently installed Devise on a rails application, and I am wondering if it is possible to get an instance of the currently logged in user in either one of the other models or controllers, and if so, how do I do that?


Source: (StackOverflow)

Override devise registrations controller

I have added a field to the sign-up form that is based on a different model, see How do I use nested attributes with the devise model for the gory details. This part is working fine.

The problem now is when I save, it is failing in the create action of the registrations controller that is supplied by devise with an Activerecord::UnknownAttributeError on this field (company).

I am assuming I need to override the registrations controller, or is there a better/easier way I should be approaching this?


Source: (StackOverflow)

Advertisements

Devise - How do I forbid certain users from signing in?

I am using Devise for authentication in my application.

How do I forbid certain users from signing in - kind of disable a user?


Source: (StackOverflow)

RoR Devise: Sign in with username OR email

What's the best way to enable users to log in with their email address OR their username? I am using warden + devise for authentication. I think it probably won't be too hard to do it but i guess i need some advice here on where to put all the stuff that is needed. Perhaps devise already provides this feature? Like in the config/initializers/devise.rb you would write:

config.authentication_keys = [ :email, :username ]

To require both username AND email for signing in. But i really want to have only one field for both username and email and require only one of them. I'll just visualize that with some ASCII art, it should look something like this in the view:

Username or Email:
[____________________]

Password:
[____________________]

[Sign In]

Source: (StackOverflow)

disabling Devise registration for production environment only

I am launching a beta site with a select group of users. I want to disable registration in the production environment only, and only for a short period of time (i.e. I don't want to nuke my registration altogether). I know I can simply hide the "sign up" link, but I suspect that hackers smarter than I can still use the RESTful routes to accomplish registrations. What's the best way to disable registration so my test/development environments still work, but production is affected? Thanks for any pointers.

I've tried pointing named scopes in such a way that "sign_up" goes to "sign_in", but it didn't work. Here's what I've tried:

devise_scope :user do
    get "users/sign_in", :to => "devise/sessions#new", :as => :sign_in
    get "users/sign_up", :to => "devise/sessions#new", :as => :sign_up
end

Ideally, we'd send the user to a "pages#registration_disabled" page or something like that. I just wanted to get something working I can play around with.

EDIT: I've changed the model as requested, then added the following to /spec/user_spec.rb

describe "validations" do
    it "should fail registration if in production mode" do
      ENV['RAILS_ENV'] = "production"
      @user = Factory(:user).should_not be_valid
    end
end

it is passing as "true" rather than false. Is there a way to mock up the production environment? I'm just spit-balling this one.

Thanks!


Source: (StackOverflow)

Setting Devise Login to be root page

I am using the following code for my routes:

  devise_for :user, 
    :as => '', 
    :path_names => { 
      :sign_in => "", 
      :sign_out => "logout", 
      :sign_up => "register" 
    }

But when I'm logged out and I goto /logout I get the following error:

No route matches {:action=>"new", :controller=>"devise/sessions"}

How do I setup the root path to be to :sign_in action?


Source: (StackOverflow)

undefined method `devise_for' in rails

after i install devise and create a user model. i rake db:migrate and then i rake routes. I then get a error with "undefined method `devise_for' for #". What could be causing this error?


Source: (StackOverflow)

Devise update user without password

I want to update users attributes without password in devise. The case is like, if password and password confirmation fields are not blank then I need devise error and if they are blank then other user attributes need to be updated. How could I do this with devise?

Thanks in advance!


Source: (StackOverflow)

"WARNING: Can't mass-assign protected attributes"

I have used RESTful techniques to generate a model (in fact, I am using Devise gem, which does that for me), and I have added new fields called first_name and last_name to the model. Migration went fine. I added attr_accessor :first_name, :last_name to the model and expected it would just work. But when I try to mass-assign new instances with Doctor.create({:first_name=>"MyName"}) etc., I am getting errors saying I can't mass-assign protected attributes.

I thought the whole point of using attr_accessor was to get around the protectedness of the fields of a model. Can you help me make sense of this message?

Edit: oh, and by the way the records do not get created either. I thought they should be since this is just a warning, but they are not on the database.

Edit2: here is my model

class Doctor < User
  has_many :patients
  has_many :prescriptions, :through=> :patients

  validates_presence_of :invitations, :on => :create, :message => "can't be blank"

  attr_accessor :invitations
end

and the schema, which doesn't have the first_name and last_name because they are created in the users table, which is the ancestor of doctors. I used single table inheritance.

create_table :doctors do |t|
  t.integer :invitations

  t.timestamps
end

and this is the migration to change the users table

add_column :users, :first_name, :string
add_column :users, :last_name, :string
add_column :users, :type, :string

EDIT: here is the seed file. I am not including the truncate_db_table method, but it works.

%w{doctors patients}.each do |m|
  truncate_db_table(m)  
end  

Doctor.create(:invitations=>5, :email=>"email@gmail.com", :first_name=>"Name", :last_name=>"LastName")
Patient.create(:doctor_id=>1, :gender=>"male", :date_of_birth=>"1991-02-24")

Source: (StackOverflow)

rails - "WARNING: Can't verify CSRF token authenticity" for json devise requests

do you know how it is possible to correctly retrieve the CSRF token to pass with a JSON request?

I know that for security reason now Rails is enforcing CSRF check on all the request type (including JSON/XML).

http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails

I could put in my controller skip_before_filter :verify_authenticity_token ,but I would loose the CRSF protection (not advisable :-) ).

In this similar (still not accepted) question

Rails/Devise - Creating new users via json request

It is suggested to

Retrieve the token with <%= form_authenticity_token %>

The question is how? Do I need to do a first call to any of my pages to retrive the token and then do my real authentication with Devise? Or it is an information one-off that I can get from my server and then use consistently (until I manually change it on the server itself)?


Source: (StackOverflow)

Rails 3 using Devise: How to allow someone to log in using their Facebook account?

I have a Rails 3 application using Devise for authentication. Now I need to allow someone to log in using their Facebook account. I think this is called Facebook Connect, but I've also heard the term Facebook Graph API, so I'm not sure which one I'm asking for.

What do I need to do in order to integrate Facebook Connect with Devise?

Solution:

This question is pretty old now. A year ago, Devise v1.2 introduced OmniAuth support. Now Devise is at v2.1 (as of this writing) and using OmniAuth is even easier. Here is a great tutorial from the Devise wiki on using the omniauth-facebook gem with Devise to allow sign-in using Facebook.

Also check out this great tutorial on registering your application and working with the Facebook Graph API.


Source: (StackOverflow)

different layout for sign_in action in devise

I'm trying to use a different/custom layout named "devise" for the sign_in action. I found this page in the devise wiki, and the second example even says you can do it per-action (in this case, sign_in action), but it shows no example of doing that. Someone on IRC told me I could try this:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout :layout_by_resource

  def layout_by_resource
    if devise_controller? && resource_name == :user && action_name == 'sign_in'
      "devise"
    else
      "application"
    end
  end
end

But it does not seem to be working as it's still loading the default application layout. I would appreciate any help.


Source: (StackOverflow)

How do I set up email confirmation with Devise?

Is there a tutorial out there that explains how to set up Devise's signup confirmation email from scratch (in both development and production), i.e. if you don't have Action Mailer set up?

Google searching has just turned up a bunch of separate pieces related to this. No one piece explains enough, and I'm not sure how they fit together. Is there a step-by-step explanation out there, or even something that explains the initial steps?


Finally got it working. Followed all the steps in the accepted answer below, then added the following to my environment.rb file:

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
   :tls => true,
   :address => "smtp.gmail.com",
   :port => 587,
   :domain => "gmail.com",
   :authentication => :login,
   :user_name => "[username]",
   :password => "[password]"
 }

Source: (StackOverflow)

How do I remove the Devise route to sign up?

I'm using Devise in a Rails 3 app, but in this case, a user must be created by an existing user, who determines what permissions he/she will have.

Because of this, I want:

  • To remove the route for users to sign up.
  • To still allow users to edit their profiles (change email address and password) after they have signed up

How can I do this?

Currently, I'm effectively removing this route by placing the following before devise_for :users:

match 'users/sign_up' => redirect('/404.html')

That works, but I imagine there's a better way, right?

Update

As Benoit Garret said, the best solution in my case is to skip creating the registrations routes en masse and just create the ones I actually want.

To do that, I first ran rake routes, then used the output to re-create the ones I wanted. The end result was this:

devise_for :users, :skip => [:registrations] 
as :user do
  get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
  put 'users' => 'devise/registrations#update', :as => 'user_registration'
end

Note that:

  • I still have :registerable in my User model
  • devise/registrations handles updating email and password
  • Updating other user attributes - permissions, etc - is handled by a different controller

Actual answer:

Remove the route for the default Devise paths; i.e.:

devise_for :users, path_names: {
  sign_up: ''
}

Source: (StackOverflow)

Devise form within a different controller

I am using a devise gem for sign_in/sign_out procedures.

I generated views files from devise, using rails g devise views

I saw there was a devise/sessions/new.html.erb file which contained a form for sign_in.

I created another file devise/sessions/_form.html.erb and did <%= render 'form' %> within a new.html.erb file, and that worked out very fine.

Now, I wanted to include this form from the different controller. So in a controller called 'main', (specifically, within view page) 'mains/index.html.erb' I included <%= render 'devise/sessions/form' %> file. It seems that inclusion worked fine, but I am getting the following error.

NameError in Mains#index

Showing /home/administrator/Ruby/site_v4_ruby/app/views/devise/sessions/_form.html.erb where line #1 raised:

undefined local variable or method `resource' for #<#<Class:0x007f1aa042d530>:0x007f1aa042b870>
Extracted source (around line #1):

1: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
2:   <p><%= f.label :email %><br />
3:   <%= f.text_field :email %></p>
4: 

It seems that form_for(resource,...) part is causing the problem (which works fine if I am on the original devise sign_in page... How can I resolve this problem in rails way?

I personally prefer to use 'render' function to include the form, rather than writing html codes inline.

Do I have to specify something (resource) within the 'main' controller?

I will appreciate your help. Thank you.


Source: (StackOverflow)