Create a customer from Devise User - ruby-on-rails

How can I create a customer class I want to be a Devise User with a role = 1.
I have my User model:
class User < ActiveRecord::Base
enum role: [:user, :customer, :admin, :producer]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :user
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable, :registerable
devise :invitable, :database_authenticatable, :confirmable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
And my Customer model
class Customer < User
end
I can specify in the customersController what is a customer like this :
# GET /customers
def index
#customers = Customer.where(:role => 1).page(params[:page])
end
But How can I modify my Customer model to self know he is a User with role = 1 so I can only get my Customers like this :
#customers = Customer.all

if you exactly need Customer.all you should looking for STI(single table inheritance) which already resolve what you trying to do

Related

Why do I keep getting this ActiveRecord::AssociationTypeMismatch error?

I have two models that have a has_many association to the same object. I have a User, an Admin, and Visits.
Users has_many Visits
Admins has_many Visits
Every time I create a Visit with a User it works, but when I do it with an Admin it gives me an error:
ActiveRecord::AssociationTypeMismatch.
The full error is this:
User(#70282715553200) expected, got #<Admin id: 2, email: "admin#gmail.com", created_at: "2019-02-07 12:08:40", updated_at: "2019-02-07 12:08:40"> which is an instance of Admin(#70282709528720)
def create
#visit = #service.visits.new(visit_params)
if user_signed_in?
#visit.user = current_user
else
#visit.user = current_admin
end
if #visit.save
redirect_to service_visits_path(#service)
else
redirect_to #services
end
end
==============================
class Admin < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and
# :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :visits, dependent: :destroy
end
==============================
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and
# :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :visits, dependent: :destroy
end
==============================
class Visit < ApplicationRecord
belongs_to :user
belongs_to :admin
belongs_to :service
end
Unless you've got some kind of polymorphism going on, which isn't documented, I'd try and change this:
if user_signed_in?
#visit.user = current_user
else
#visit.user = current_admin
end
To this:
if user_signed_in?
#visit.user = current_user
else
#visit.admin = current_admin # this line
end
Your Visit model says a visit has both one User, and one Admin, so you have to assign the current_admin to the #visit.admin, not #visit.user.
If you're using Rails 5, you'll also need to update your model as below:
class Visit < ApplicationRecord
belongs_to :user, optional: true
belongs_to :admin, optional: true
belongs_to :service
end
As I note in my comment below, the suggestion from #bo-oz should be given considerable consideration. I haven't seen User and Admin tables typically split out as you've done in production applications. The concept of 'admin' is typically handled as a separate Role model (the rolify gem is good for this), or more simply as a boolean on the User model.
I think what you are trying to do us just plain wrong. An Admin is a User as well. You should remove the Admin model entirely. If you need to assign additional capabilities / rights to someone, you should either create an additional attribute (admin boolean yes/no), or create some kind of Role Based model. Have a look at Rolify gem.
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and
:omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :visits, dependent: :destroy
def is_admin?
// return true if user is admin
end
end
class Visit < ApplicationRecord
belongs_to :user
belongs_to :service
end
def create
#visit = #service.visits.new(visit_params)
if user_signed_in?
#visit.user = current_user
else
if #visit.save
redirect_to service_visits_path(#service)
else
redirect_to #services
end
One warning though.... the user is mandatory is this relationship, so this would break if someone is not logged in! Think about it... either don't create a Visit, or create an Anonynous visit.

how to add forgot password field using devise gem

I am really new to rails. im using devise gem. now,im trying to implement forget password field in my application.I have been working for hours, but I haven't really had any results. How do I set this up? I am using rails 4
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, #:registerable,
:recoverable, :rememberable, :trackable, :validatable
enum role: [:creator, :editor, :curator, :super_admin]
enum status: {:inprogress => 1, :completed => 2}
#has_many :albums
has_many :order_states
has_many :products, through: :order_states
has_many :tagging
has_many :pictures, through: :tagging
def self.authenticate(username, password)
user = User.find_for_authentication(email: username)
if user
user.valid_password?(password) ? user : nil
else
nil
end
end
def generate_authentication_token
token = SecureRandom.hex
self.update_columns(auth_token: token, token_created_at: Time.zone.now)
token
end
end

Rails - devise with devise_token_auth not sending confirmation email

I work on project (ruby '2.2.0', rails '4.2.3') which use both standard devise user management (for web page) and devise_token_auth (for API part of the service). Everything works fine unless I
include DeviseTokenAuth::Concerns::User
in the models/user.rb. Then sending confirmation emails after user registration does not occur.
I would be grateful for the solution of this problem.
My models/user.rb:
class User < ActiveRecord::Base
# Include devise modules.
devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :omniauthable
include DeviseTokenAuth::Concerns::User
enum role: [:user, :vip, :admin]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :user
end
end
routes.rb:
Rails.application.routes.draw do
# standard devise routes available at /users
# NOTE: make sure this comes first!!!
devise_for :users
# token auth routes available at /api/v1/auth
namespace :api do
scope :v1 do
mount_devise_token_auth_for 'User', at: 'auth'
end
end
end
I got the same problem to you. This workaround helped me
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable
include DeviseTokenAuth::Concerns::User
after_create :send_confirmation_email, if: -> { !Rails.env.test? && User.devise_modules.include?(:confirmable) }
private
def send_confirmation_email
self.send_confirmation_instructions
end
end

Rails undefined method ReactJS

I am getting an error on my application undefined method 'preference' for #<User:0x007fb3cc1c3b80>. Following were my accounts controller:
class AccountsController < ApplicationController
before_action :authenticate_user!
def edit
#render html: 'Edit your account'
render component: 'AccountsEdit', props: {
preference: PreferenceSerializer.new(current_user.preference)
}, tag: 'div'
end
def update
#preference = current_user.preference
if #preference.update_attributes(preference_params)
render json: { data: 'SUCCESS!' }
else
render json: { data: 'FAIL!' }
end
end
private
def preference_params
params.require(:preference).permit(:display_name, :notify_on_answer, :daily_digest)
end
end
And my User and Preference model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
class Preference < ActiveRecord::Base
belongs_to :user
end
Seems all look alright, but i keep getting the same error. Am i missing something here? Thanks!!
Inside your User model add the relation to the Preference model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_a: :preference # Or has_many: :preferences
end

How to set up custom validation before an association is created in Rails

Not sure if the question makes sense so I'll describe through an example:
Basically I have a company model in my app and a company employee. The employee is a devise model and can sign up/sign in. I have a wizard set up for the employee to select the company they work for after signing up, so the model accepts nested attributes for company.
During the stage where they select the company they work for, I want to set up a validation to ensure they only select the company they work for by matching the employee's email domain with the company's email domain in my db. At which point should i do this? Should I set up a custom validator or use a callback?
Here's my code:
Employee:
class Employee < ActiveRecord::Base
##################
# Base
###################
rolify
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :company_id, :company_attributes
##################
# Associations
###################
belongs_to :company
accepts_nested_attributes_for :company
has_many :authentications, dependent: :destroy
end
Company:
class Company < ActiveRecord::Base
##################
# Base
###################
attr_accessible :name, :address_attributes, :email, :phone_number, :website, :confirmed
##################
# Associations
###################
has_one :address
accepts_nested_attributes_for :address
has_many :employees
end
And here is the controller which is responsible for employees selecting a company, it's a wicked gem wizard controller.
class EmployeeStepsController < ApplicationController
before_filter :authenticate_employee!
include Wicked::Wizard
steps :personal, :company_details, :enter_company_details
def show
#employee = current_employee
case step
when :enter_company_details
if #employee.company
skip_step
else
#employee.build_company.build_address
end
end
render_wizard
end
def update
#employee = current_employee
#employee.attributes = params[:employee]
render_wizard #employee
end
private
def finish_wizard_path
employee_url(#employee)
end
end
I have another controller which deals with adding companies into the site separately for site admins but I only want to trigger the email validation in the wizard controller aka when employees are selecting their company. Any advice on this?
class Employee < ActiveRecord::Base
##################
# Base
###################
rolify
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :company_id, :company_attributes
##################
# Associations
###################
belongs_to :company
accepts_nested_attributes_for :company
has_many :authentications, dependent: :destroy
# HERE
validate :my_custom_vaildator
private
def my_custom_vaildator
# do stuff .....
# based off that stuff add errors
if some_logic_about_your_company?
self.errors.add(:base, "select the company you work for.")
elsif some_other_logic?
self.errors.add(:name, "your name sucks.")
end
end
end
REMEMBER:
never return nil or false. If you do it will go BANG!
=)
all this said the front end should never allow them to select something that isn't allowed.

Resources