Development using User and Profile + Omniauth Facebook models

Our application uses Devise for Registration and works great with the user model and model.

Save the registration information from the form to the Users table and create a profile in the Profiles table in SQL with other information and insert it into user_id.

Omniauth Facebook is working to save things in the user model, but I want to save the name, username obtained from Facebook Auth, to the profile model, for example, to register Devise.


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 and :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 do |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 do |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 (for handling permissions of custom fields)

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_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

- , Omniauth Facebook , Devise, , User and Profile : P?

:)

+4
2

, facebook , , facebook, facebook , db, .

find_for_facebook_oauth(auth). -

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

                        )
    return user

  end
end

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    # You need to implement the method below in your 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 is confirmed else it'll throw an 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

Yahoo, , , facebook, user profile find_for_facebook_oauth(auth)

user = User.new(#user attributes)
user.build_profile(#profile attributes)
return user # and then return initialised user 

db, else facebook , .

+3

devos omniauth

def self.find_for_facebook_oauth(auth)
  where(auth.slice(:provider, :uid)).first_or_create do |user|
    user.provider = auth.provider
    user.uid = auth.uid
    user.email = auth.info.email
    user.password = Devise.friendly_token[0,20]
  end
end

,

user.username = auth.info.nickname

,

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   def facebook
     raise request.env["omniauth.auth"].to_yaml # <----------
     .
     .
     .

omniauth-facebook-gem, , ,

0

Source: https://habr.com/ru/post/1543737/


All Articles