Question

I've been looking at my code for some time now and can't work out where the errors are with Devise. I've added a few additional lines to the Sign Up view and changed everything as described in the Devise Readme, but the additional fields are not showing up, only the usual Email, Password and Confirm Password fields are. My users are called Knockers, in case anyone was wondering!

Here is my views page (registrations\new.html.erb):

<h2>Sign up</h2>

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

   <div><%= f.text_field :first_name %></div>

   <div><%= f.text_field :last_name %></div>

   <div><%= f.text_field :username %></div>

   <div><%= f.text_field :gender %></div>

   <div><%= f.date_field :dob %></div>

   <div><%= f.label :email %><br />
   <%= f.email_field :email, :autofocus => true %></div>

   <div><%= f.label :password %><br />
   <%= f.password_field :password %></div>

   <div><%= f.label :password_confirmation %><br />
   <%= f.password_field :password_confirmation %></div>

   <div><%= f.submit "Sign up" %></div>
<% end %>

<% if knocker_signed_in? %>
   Signed in as <%= current_knocker.name %>. Not you?
   <%= link_to "Sign out", destroy_knocker_session_path,:method => :delete %>
<% else %>
   <%= link_to "Sign up", new_knocker_registration_path %> or
   <%= link_to "Sign in", new_knocker_session_path %>
   <%= link_to "Sign in with Facebook", knocker_omniauth_authorize_path(:facebook) %>
<% end %>

<% if knocker_signed_in? %>
   Signed in as <%= current_knocker.name %>. Not you?
   <%= link_to "Sign out", destroy_knocker_session_path,:method => :delete %>
<% else %>
   <%= link_to "Sign up", new_knocker_registration_path %> or
   <%= link_to "Sign in", new_knocker_session_path %>
   <%= link_to "Sign in with Twitter", knocker_omniauth_authorize_path(:twitter) %>
<% end %>

<% if knocker_signed_in? %>
   Signed in as <%= current_knocker.name %>. Not you?
   <%= link_to "Sign out", destroy_knocker_session_path,:method => :delete %>
<% else %>
   <%= link_to "Sign up", new_knocker_registration_path %> or
   <%= link_to "Sign in", new_knocker_session_path %>
   <%= link_to "Sign in with Google", knocker_omniauth_authorize_path(:google_oauth2) %>
<% end %>

<%= render "knockers/shared/links" %>

My model page (\knocker.rb)

Class Knocker < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:facebook, :twitter, :google_oauth2]

    before_save { self.username = username.downcase }

    validates :first_name,    presence: true, 
                          length: { maximum: 25 }
    validates :last_name,     presence: true, 
                          length: { maximum: 25 }
    VALID_USERNAME_REGEX = /\A[\w+\-._]+\z/i
    validates :username,      presence: true, 
                          length: { maximum: 20 },
                          format: { with: VALID_USERNAME_REGEX },
                          uniqueness: { case_sensitive: false }
    validates :email,             presence: true
    validates :password,          presence: true
    validates :dob,                 presence: true
    validates :gender,            presence: true
    validates :postcode,          presence: true



def self.find_for_facebook_oauth(auth)
    where(auth.slice(:provider, :uid)).first_or_create do |knocker|
      knocker.provider = auth.provider
      knocker.uid = auth.uid
      knocker.email = auth.info.email
      knocker.password = Devise.friendly_token[0,20]
      #knocker.first_name = auth.info.name   # assuming the user model has a name
      #knocker.image = auth.info.image # assuming the user model has an image
    end
end

def self.find_for_twitter_oauth(auth, signed_in_resource=nil)
    knocker = Knocker.where(:provider => auth.provider, :uid => auth.uid).first
    if knocker
        return knocker
    else
        registered_knocker = Knocker.where(:email => auth.uid + "@twitter.com").first
        if registered_knocker
            return registered_knocker
        else
            knocker = Knocker.create(full_name:auth.extra.raw_info.name,
                    provider:auth.provider,
                    uid:auth.uid,
                    email:auth.uid+"@twitter.com",
                    password:Devise.friendly_token[0,20],
                    username:auth.info.nickname,
                    about:auth.info.description                    )
        end
     end
   end

   def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
    data = access_token.info
    knocker = Knocker.where(:provider => access_token.provider, :uid => access_token.uid ).first
    if knocker
      return knocker
    else
      registered_knocker = Knocker.where(:email => access_token.info.email).first
      if registered_knocker
        return registered_knocker
      else
        knocker = Knocker.create(first_name: data["first_name"],
          last_name: data["last_name"],
          provider:access_token.provider,
          email: data["email"],
          uid: access_token.uid ,
          password: Devise.friendly_token[0,20],
          gender: data["gender"],
          dob: data["birthday"]
        )
      end
    end
end

def self.new_with_session(params, session)
    super.tap do |knocker|
        if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
            knocker.email = data["email"] if knocker.email.blank?
        end
    end
end

def name
    first_name + " " + last_name
end
 end

My database migration:

 class DeviseCreateKnockers < ActiveRecord::Migration
   def change
     create_table(:knockers) do |t|
       t.string :first_name,         :null => false
       t.string :last_name,          :null => false
       t.string :username,           :null => false
       t.string :town
       t.string :postcode
       t.float :latitude                       
       t.float :longitude           
       t.date :dob,                  :null => false
       t.text :about
       t.string :gender,             :null => false
       t.string :nationality

       ## Database authenticatable
       t.string :email,              :null => false, :default => ""
       t.string :encrypted_password, :null => false, :default => ""

       ## Omniauth data
       t.string :provider
       t.string :uid

       ## Recoverable
       t.string   :reset_password_token
       t.datetime :reset_password_sent_at

       ## Rememberable
       t.datetime :remember_created_at

       ## Trackable
       t.integer  :sign_in_count, :default => 0, :null => false
       t.datetime :current_sign_in_at
       t.datetime :last_sign_in_at
       t.string   :current_sign_in_ip
       t.string   :last_sign_in_ip

       ## Confirmable
       # t.string   :confirmation_token
       # t.datetime :confirmed_at
       # t.datetime :confirmation_sent_at
       # t.string   :unconfirmed_email # Only if using reconfirmable

       ## Lockable
       t.integer  :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
       t.string   :unlock_token # Only if unlock strategy is :email or :both
       # t.datetime :locked_at


       t.timestamps
     end

     add_index :knockers, :email,                :unique => true
     add_index :knockers, :reset_password_token, :unique => true
     add_index :knockers, :username,              :unique => true
     add_index :knockers, :latitude
     add_index :knockers, :longitude
     add_index :knockers, :dob
     # add_index :knockers, :confirmation_token,   :unique => true
     # add_index :knockers, :unlock_token,         :unique => true
   end
 end

and finally my Application Controller:

 class ApplicationController < ActionController::Base
   # Prevent CSRF attacks by raising an exception.
   # For APIs, you may want to use :null_session instead.
   protect_from_forgery with: :exception
   before_filter :configure_permitted_parameters, if: :devise_controller?

   protected

   def configure_permitted_parameters
     devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :first_name, :last_name, :gender, :dob, :email, :password, :password_confirmation) }
   end
 end

Any help would be greatly appreciated. I've looked on here through a few problems, but most of them just seem to be in getting the wrong field type... can't see what the problem is here unless it's something to do with a badly implemented OAuth problem.

Was it helpful?

Solution

Rename the knockers folder under application_name/app/views directory to devise.

While generating the views you by mistake generated them as rails generate devise:views knockers instead of rails generate devise:views.

You use rails generate devise:views knockers to generate views if you have multiple devise models and you need different views(customizations) for them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top