How to check if the user should be assigned the role admin - ruby-on-rails

The goal of this method is to check when a user signs up, if they are on the list of users that should be admins.
I am new to Ruby and think it is just a syntax error:
def set_role
if self[:email] == ("email#gmail.com" || "sample#gmail.com" || "test#gmail.com")
self[:role] = "admin"
else
self[:role] = "customer"
end
end

This would be a good time to use a case statement:
def set_role
self[:role] = case self[:email]
when "email#gmail.com", "sample#gmail.com", "test#gmail.com"
'admin'
else
'customer'
end
end
It's easy to add new values to the when test.

You want to check if an array of emails includes the current email like this:
def set_role
if ["email#gmail.com", "sample#gmail.com", "test#gmail.com"].include?(self[:email])
self[:role] = "admin"
else
self[:role] = "customer"
end
end
This code could also be improved:
def set_role
admin_emails = ["email#gmail.com", "sample#gmail.com", "test#gmail.com"]
self[:role] = if admin_emails.include?(self[:email])
"admin"
else
"customer"
end
end

Related

DRYing up similar code in controller methods

I've got two methods in a controller with very similar code. Wondering how I could DRY them up! They both utilize csv-importer gem to parse a csv file.
sales_controller.rb
def import_csv_test
user_id = params[:user_id]
import = ImportSaleCSV.new(file: params[:file]) do
after_build do |sale|
sale.user_id = user_id
skip! if sale.email == nil
skip! if sale.order_date == nil
skip! if sale.amount == nil
end
end
import.run!
redirect_to lifecycle_grid_sales_path, notice: import.report.message
end
def import_ftp
user_id = params[:user_id]
import = ImportSaleCSV.new(path: './public/uploads/gotcha.csv') do
after_build do |sale|
sale.user_id = user_id
skip! if sale.email == nil
skip! if sale.order_date == nil
skip! if sale.amount == nil
end
end
import.run!
redirect_to lifecycle_grid_sales_path, notice: import.report.message
end
Thanks!
I think you can extract a class to do the heavy lifting.
class ImportSaleCSVCreator
def initialize(csv_options = {}, csv_attributes = {})
#csv_options = csv_options
#csv_attributes = csv_attributes
end
def build
ImportSaleCSV.new(csv_options) do
after_build do |sale|
csv_attributes.each { |k, v| sale.public_send("#{k}=", v) }
skip! if sale.email.nil? || sale.order_date.nil? || sale.amount.nil?
end
end
end
private
attr_reader :csv_options, :csv_attributes
end
class Controller
def import_csv
import = ImportSaleCSVCreator.new({ file: params[:file] }, { user_id: params[:user_id] })
import.run!
end
def import_ftp
import = ImportSaleCSVCreator.new({ path: './gotcha.csv' }, { user_id: params[:user_id] })
import.run!
end
end
Make sure you check attributes passed. Especially when dealing with files, paths, etc. You might want to filter the parameters in ImportSaleCSVCreator.
You may refactor both your methods into single one:
def import(hash)
user_id = params[:user_id]
import = ImportSaleCSV.new(hash) do
after_build do |sale|
sale.user_id = user_id
skip! if sale.email == nil
skip! if sale.order_date == nil
skip! if sale.amount == nil
end
end
import.run!
redirect_to lifecycle_grid_sales_path, notice: import.report.message
end
And then call it:
import({file: params[:file]})
import({path: './public/uploads/gotcha.csv'})
It doesn't seem that method belongs to your controller so you may want to extract it somewhere. I encourage you to check this great article and extract your method into brand new Service object.

How to get object value in ActiveRecord Model?

I want to create custom validation inside The Model.
But nothing in return when i tried to get that value from the variable
This is my model
validate :permanent_event_check
private
def permanent_event_check
param_activity = #activity
# puts "param_activityparam_activityparam_activity"
# puts #activity
# puts param_activity
# puts "param_activityparam_activityparam_activityparam_activity"
if param_activity.permanent == "false"
if param_activity.start_at == "" || param_activity.end_at == ""
#activity.errors[:base] << "You can't leave start and end date blank with Permanent Event"
return false
end
end
end
This is my controller
def create
#activity = admin_current_user.activities.build(activity_param)
if #activity.save
flash[:success] = "Activity Created!"
redirect_to admin_dashboard_url
else
render 'new'
end
end
private
def activity_param
params.require(:activity).permit(:name,:details,:start_at,:end_at,
:activity_image01_url,:activity_image02_url,:activity_image03_url,
:youtube_url,:capacity,:booking_status,:rules,:apply_details,
:payment_price,:payment_need,:avaliable,:rating,:temple_id)
end
But it return nil when i tried to get the value from #activity inside my model.
How can i fix this?
Thanks!
You cannot assign the object like that in the model, instead you van take self.
validates :permanent_event_check
private
def permanent_event_check
if self.permanent == "false"
if self.start_at == "" || self.end_at == ""
self.errors[:base] << "You can't leave start and end date blank with Permanent Event"
return false
end
end
end
I assume that permanent is boolean, start_at and end_at - datetime.
validate :permanent_event_check, unless :permanent
private
def permanent_event_check
# if start_at and end_at are not filled they will be nil which is interpreted as false
unless start_at && end_at
self.errors[:base] << "You can't leave start and end date blank with Permanent Event"
end
end

Update value with first_or_create in rails

I have a table 'Likes' with columns business_id, user_id and liked(0,1) and a function 'change_like_status'.
Now on every function call, If the value is 1 then set it to 0 (or vice versa) and if record doesn't exists then create one with value 1.
The first_or_create method is working just fine but how can i toggle value of column 'liked' while using this method?
Here is my function:
def change_like_status
if current_user.present?
status = Like.where("business_id = ? AND user_id = ?",params['id'],current_user.id).first_or_create(:business_id => params['id'],:user_id => current_user.id,:liked => '1')
abort status.inspect
else
return render :json => {:status => false,:msg=>"You need to sign in before performing this action."}
end
end
In you controller, make the changes
def change_like_status
if current_user
status = Like.create_or_change_status(params[:id], current_user.id)
else
return render json: { status: false, msg: "You need to sign in before performing this action." }
end
end
In your model like.rb file, add a method
def self.create_or_change_status(business_id, user_id)
status = where(business_id: business_id, user_id: user_id).first
if status.nil?
status = create({business_id: business_id, user_id: user_id, liked: 1})
else
status.update_attributes(liked: !status.liked)
end
status
end
def change_like_status
if current_user
current_user.likes.find_by(business_id: params[:id]).switch_status!
else
return render json: { status: false, msg: "You need to sign in before performing this action." }
end
end
class Like
def switch_status!
self.update_column :liked, !liked
end
end
other approach should be something like that
class Like
def switch_status!
self.update_column :liked, !liked
end
end
class User
def likes id
likes_for_business id
end
def likes_for_business(id)
likes.find_by(business_id: id) || likes.create(:business_id: id, liked: true)
end
end
# controller
current_user.likes(params[:id]).switch_status!

Refactoring rails model to remove string literals from condition

I get a warning every time I start my server that I have string literals in my conditions. What does this mean, and how can I improve my code to fix this and stop getting the warning?
def partner_cars
if self.role == 'Garage Employee' || self.role == 'Garage Manager'
self.cars
elsif self.role == 'Company Employee' || 'Company Manager'
self.company.cars
else
nil
end
end
def partner_users
if self.role == 'Garage Employee' || self.role == 'Garage Manager'
allowed_users = self.users
elsif self.role == 'Company Employee' || 'Company Manager'
allowed_users = self.company.users
else
allowed_users = nil
end
allowed_users.uniq
end
Any help on how to refactor this code would be much appreciated, thanks!
The error comes from the line elsif self.role == 'Company Employee' || 'Company Manager'. Instead, it should be elsif self.role == 'Company Employee' || self.role == 'Company Manager'.
However, I would refactor your code to use case statements like this:
def partner_cars
case role
when 'Garage Employee', 'Garage Manager' then cars
when 'Company Employee', 'Company Manager' then company.cars
end
end
def partner_users
allowed_users =
case role
when 'Garage Employee', 'Garage Manager' then users
when 'Company Employee', 'Company Manager' then company.users
end
allowed_users.try(:uniq)
end
Without knowing your data structure, its hard to suggest a refactoring approach.
def partner_cars
if garage_roles.include?(self.role)
...some code
elsif employee_roles.include?(self.role)
..some code
end
end
private
def garage_roles
['Garage Employee', 'Garage Manager']
end
Even better would be to set up these methods in your role model.
class Role
def works_for_garage?
title == 'Garage Manager' || 'Garage Employee'
end
end

Rails - adding attributes on a user before it's created

When a user registers with twitter I'm trying to add his name, location, etc. to his user record. I think I want to do something like user.build
Here is the controller. This is what happens:
user = User.new
user.apply_omniauth(omni)
if user.save
flash[:notice] = "Logged In!"
sign_in_and_redirect(:user, user)
else
session[:omniauth] = omni.except('extra')
redirect_to new_user_registration_path
end
When a user doesn't exist with twitter, the user is redirected to the registration path where they finish registering. I want to add the extra stuff from twitter to their yet to be saved user account. I can't do it in the user.apply_omniauth(omni) method because that saves to the authentications table.
Any ideas?
Thanks!
You can create a flag in apply_omniauth method to make a decision to save or not.
app/models/user.rb
# def apply_omniauth(omniauth) => def apply_omniauth(omniauth, save_it)
# apply_omniauth with save it flag
def apply_omniauth(omniauth, save_it = false)
case omniauth['provider']
when 'facebook'
self.apply_facebook(omniauth)
end
self.email = omniauth['user_info']['email']
if email.blank ? build_authentications(omniauth, save_it)
end
#build authentications
def build_authentications(omniauth, save_it = false)
auth_params = {: provider = > omniauth['provider'],
: uid = > omniauth['uid'],
: token = > (omniauth['credentials']['token'] rescue nil)
}
if save_it authentications.create!(auth_params)
else authentications.build(auth_params)
end
end
#force to save
def apply_omniauth!(omniauth)
apply_omniauth(omniauth, true)
end

Resources