ruby on rails - Devise with Models User and Profile + Omniauth Facebook -


our app uses devise registration , works perfect user model , profile model.

save registration infos form users table , create profile in profiles table on sql infos , nested user_id.

the omniauth facebook working save things user model, want save name, username fetched facebook auth profile model devise registration do.


table users

| id | email | encrypted_password | reset_password_token | reset_password_sent_at | remember_created_at | sign_in_count | current_sign_in_at | last_sign_in_at | current_sign_in_ip | last_sign_in_ip | created_at | updated_at | role_id | provider | uid | 

table profiles

| id | user_id | username | name | lastname | gender | birthday | created_at | updated_at | 

model user.rb

class user < activerecord::base    has_one :profile, :dependent => :destroy, autosave: true   accepts_nested_attributes_for :profile    # include default devise modules. others available are:   # :confirmable, :lockable, :timeoutable , :omniauthable   devise :database_authenticatable, :registerable,          :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:facebook]    belongs_to :role   before_create :set_default_role    def self.find_for_facebook_oauth(auth)     where(auth.slice(:provider, :uid)).first_or_create |user|       user.provider = auth.provider       user.uid = auth.uid       user.email = auth.info.email       user.password = devise.friendly_token[0,20]     end   end    def self.new_with_session(params, session)     super.tap |user|       if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]         user.email = data["email"] if user.email.blank?       end     end   end    private   def set_default_role     self.role ||= role.find_by_name('registered')   end  end 

model profile.rb

class profile < activerecord::base    belongs_to :user    validates :username, presence: true, length: {maximum: 255}, uniqueness: { case_sensitive: false }, format: { with: /\a[a-za-z0-9]*\z/, message: "deve contar apenas letras e nĂºmeros" }   validates :name, presence: true, length: {maximum: 255}   validates :lastname, presence: true, length: {maximum: 255}   validates :gender, presence: true, inclusion: %w(m f)   validates :birthday, presence: true  end 

controller application_controller.rb (to handle permits of custom fields)

class applicationcontroller < actioncontroller::base   # prevent csrf attacks raising exception.   # apis, may want use :null_session instead.   protect_from_forgery with: :exception    before_action :configure_permitted_parameters, if: :devise_controller?    protected    def configure_permitted_parameters     devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :provider, :uid, profile_attributes: [:name, :lastname, :username, :birthday, :gender, :id]) }     devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:email, :password, :remember_me, :provider, :uid) }     devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password) }   end  end 

anyone knows how can make omniauth facebook runs devise registration create profile user, integration 2 models user , profile without break devise registration :p ?

thank :)

i don't know facebook sign or sign in flow of app i'm going assume when user clicks on sign in or sign facebook, app fetches email facebook , create new user if email not present in db else sign them in.

to achieve need override find_for_facebook_oauth(auth) method. can in method

def self.find_for_facebook_oauth(auth)   if user = user.find_by_email(auth.info.email)  # search db user email coming fb     return user  #returns user can sign him/her in   else     user = user.create(provider: auth.provider,    # create new user if user same email not present                        uid: auth.uid,                        email: auth.info.email,                        password: devise.friendly_token[0,20])     user.create_profile(name: auth.info.name, # need check how access these attributes auth hash using debugger or pry                         #your other profile attributes                          )     return user    end end 

and callback method same

class users::omniauthcallbackscontroller < devise::omniauthcallbackscontroller   def facebook     # need implement method below in model (e.g. app/models/user.rb)     @user = user.find_for_facebook_oauth(request.env["omniauth.auth"])      if @user.persisted?       sign_in_and_redirect @user, :event => :authentication #make sure user confirmed else it'll throw error       set_flash_message(:notice, :success, :kind => "facebook") if is_navigational_format?     else       session["devise.facebook_data"] = request.env["omniauth.auth"]       redirect_to new_user_registration_url     end   end end 

if flow yahoo render form autofilled fields using data coming facebook instead of creating can initialise user , profile inside find_for_facebook_oauth(auth) method statements

user = user.new(#user attributes) user.build_profile(#profile attributes) return user # , return initialised user  

since user not in db execute else block in facebook callback method , render sign in page fields autofilled.


Comments

Popular posts from this blog

database - VFP Grid + SQL server 2008 - grid not showing correctly -

jquery - Set jPicker field to empty value -

.htaccess - htaccess convert request to clean url and add slash at the end of the url -