Saturday 10 September 2016

Belongs_to Association in Devise Model Rails 5

Here, we are going to create a relationship between Account has_many user and user belongs_to account. User can create through Devise gem sign up.

So, in Gemfile -

gem 'devise'

Run the bundle command to install it.

$ bundle install

Next, you need to run the devise generator -


$ rails generate devise:install

Now, create a User model and configure it with the default Devise modules -


$ rails generate devise User

Then run

$ rake db:migrate

We have done set up of devise for user model -

Now, we will do association between Account and User Model.

In account.rb


class Account < ApplicationRecord
  has_many :users, inverse_of: :account, dependent: :destroy
end

In user.rb


class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  ######### Association####################
  belongs_to :account, inverse_of: :users
 
end


For this association we have to add refrence field of account_id in users table -

$ rails g migration add_account_id_to_users account_id:integer

Then run

$ rake db:migrate

Now, we have to override devise registeration controller for permit account_id params -

$ rails generate devise:controllers users registrations

In routes.rb

devise_for :users, controllers: {registrations: 'users/registrations'}

Now, we can permit the account_id params in registrations controllers -

In uncomment registrations controllers the follwing lines -

before_action :configure_sign_up_params, only: [:create]


 def create
    super
  end

 # account_id params to permit, append them to the sanitizer.
  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:account_id])
  end

Till now, we have ovveride the registrations controller and permit the extra params but when we will try to sign up a user it will through a exception of account id can't be blank.

For the handle above situation we have to assign the value of account_id in user table before creating user but before_create callback doesn't work in this condition due to validation of devise model. So we have to use before_validation.

In user.rb

 before_validation :create_account
 # Here we creating account and assing account_id to user
  def create_account
    account = Account.new(name: 'name')
    if account.save
      self.account_id = account.id
    end
  end




No comments:

Post a Comment