我有一个带有两个具有非常相似行为的控制器的rails应用程序。
一个是与Hotel概念相关的UsersController,另一个也是UsersController,但与关联概念有关,因此它存储在一个文件夹关联中:class Api::V1::Association::UsersController < Api::V1::BaseController
这些控制器具有非常相似的行为,方法存在细微差别(它们依赖于某些变量的不同数据库表......)。我正在阅读有关继承的内容,并认为从Association::UsersController
继承UsersController
可能会很有趣。你认为这可能是我的理由吗?例如,我一直在尝试重写Association::UsersController
的方法邀请来使用继承,但我对如何做它有点困惑。如果Association::UsersController
继承自usersController
,您能否告诉我如何重写此方法?这两个控制器的外观如下:
users_controller.rb:
class Api::V1::UsersController < Api::V1::BaseController
skip_after_action :verify_authorized, only: [:invite, :update_specific, :show]
before_action :set_user, except: [:invite, :index, :update_specific]
before_action :set_account, only: [:index, :invite, :show]
# creates user linked to account / only account owner can create users linked to account
# input account_id & email
def invite
unless current_user.id != @account.admin_user_id
user_already_exists_or_email_blank?
set_new_user
ActiveRecord::Base.transaction do
set_hotels_access
save_user_and_send_invitation_email
end
else
render_error("not_admin")
end
end
def show
if ((current_user == @user) || (@account.admin == current_user))
else
render_error("unauthorized")
end
end
# admin can update employee or manager
def update_specific
@user_to_update = User.find(params[:id])
if @user_to_update.account != current_user.created_account
render_error("unauthorized")
else
ActiveRecord::Base.transaction do
update_user_and_hotels_access
end
end
end
# update self
def update
authorize @user
if @user.update(user_params)
render_success("updated")
else
render_error("")
end
end
def destroy
authorize @user
if @user.destroy
render json: {message: "User successfully destroyed"}
else
render json: {error: "There was an error please try again"}
end
end
# envoyer account params
def index
if (current_user.created_account == @account) || ((current_user.account == @account) && (current_user.status == "manager"))
@users = policy_scope(User).where(account: @account)
@admin = @account.admin
render json: {users: @users, admin: @admin}
else
render json: {message: "Unauthorized"}
end
end
# unlincks user from account
#input user_id
def unlinck
authorize @user
@user.account = nil
if @user.save && @user.hotels.delete_all.nil?
render json: {user: @user}
else
render_error("db")
end
end
private
def user_already_exists_or_email_blank?
if User.find_by_email(params[:user][:email])
render_error("mail_exists") and return
elsif params[:user][:email].blank?
render_error("empty_email") and return
end
end
def set_new_user
password = SecureRandom.hex
invitation_token = SecureRandom.uuid
@user = User.new(first_name: params[:user][:first_name], last_name: params[:user][:last_name], telephone: params[:user][:telephone], account_id: params[:user][:account_id], email: params[:user][:email], status: params[:user][:status], password: password, password_confirmation: password, invitation_token: invitation_token, invitation_created_at: Time.now, role: "hotel")
end
def set_hotels_access
if params[:hotel_access].first == "all"
@hotels = @account.hotels
else
@hotels = Hotel.where(id: params[:hotel_access])
end
end
def save_user_and_send_invitation_email
if @user.save && @user.hotels << @hotels
if UserMailer.send_invitation(@user, params[:app_base_url]).deliver_now
@user.invitation_sent_at = Time.now
if @user.save
render_success("mail_sent")
else
render_error("db")
end
else
render_error("mail_processing")
end
else
render_error("db")
end
end
def update_user_and_hotels_access
@hotels = Hotel.where(id: params[:hotel_access])
if @user_to_update.hotels.destroy_all
if @user_to_update.hotels << @hotels
if @user_to_update.update(user_params)
render json: {message: "User successfully updated"}
else
render_error("db")
end
else
render("db")
end
else
render_error("db")
end
end
def set_user
@user = User.find(params[:id])
end
def set_account
if params[:account_id]
@account = Account.find(params[:account_id])
elsif params[:user][:account_id]
@account = Account.find(params[:user][:account_id])
end
end
def user_params
params.require(:user).permit(
:email,
:account_id,
:first_name,
:last_name,
:telephone,
:position,
:status,
:user_id
)
end
def render_error(error_type)
case error_type
when "not_admin"
render json: {error: "You are not allowed to create a user for this account"}
when "mail_exists"
render json: {error: "Please fill the email field and try again"}
when "empty_email"
render json: {error: "Please fill the email field and try again"}
when "mail_processing"
render json: { error: "We couldnt send an email to your invitee. Please try again" }
when "db"
render json: {error: "An error occured. Please try again"}
when "unauthorized"
render json: {error: "Unauthorized"}
else
render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity
end
end
def render_success(success_type)
case success_type
when "mail_sent"
render json: { success: "An email was sent to your collaborator asking him to join your Quickbed team." }
when "password_changed"
render json: {success: "Your password was successfully changed"}
when "updated"
render json: {success: "Your infos were successfully updated"}
end
end
end
关联/ users_controller.rb
class Api::V1::Association::UsersController < Api::V1::BaseController
skip_after_action :verify_authorized, only: [:invite, :update_specific, :show]
before_action :set_user, except: [:invite, :index, :update_specific]
before_action :set_account_asso, only: [:index, :show, :invite]
# creates user linked to account / only account owner can create users linked to account
# input account_id & email
def invite
unless current_user.id != @account_asso.admin_user_id
user_already_exists_or_email_blank?
set_new_user
ActiveRecord::Base.transaction do
set_offices_access
save_user_and_send_invitation_email
end
else
render_error("not_admin")
end
end
def show
if ((current_user == @user) || (@account_asso.admin == current_user))
else
render_error("unauthorized")
end
end
# admin can update employee or manager
def update_specific
@user_to_update = User.find(params[:id])
if @user_to_update.account != current_user.created_account
render_error("unauthorized")
else
ActiveRecord::Base.transaction do
update_user_and_offices_access
end
end
end
# update self
def update
authorize @user
if @user.update(user_params)
render_success("updated")
else
render_error("db")
end
end
def destroy
authorize @user
if @user.destroy
render json: {message: "User successfully destroyed"}
else
render_error("db")
end
end
# envoyer account params
def index
if (current_user.created_account_asso == @account_asso) || ((current_user.account_asso == @account_asso) && (current_user.status == "manager"))
@users = policy_scope(User).where(account_asso: @account_asso)
@admin = @account_asso.admin
render json: {users: @users, admin: @admin}
else
render_error("unauthorized")
end
end
# unlincks user from account
#input user_id
def unlinck
authorize @user
@user.account_asso = nil
if @user.save && @user.offices.delete_all.nil?
render json: {user: @user}
else
render_error("db")
end
end
private
def user_already_exists_or_email_blank?
if User.find_by_email(params[:user][:email])
render_error("mail_exists") and return
elsif params[:user][:email].blank?
render_error("empty_email") and return
end
end
def set_new_user
password = SecureRandom.hex
invitation_token = SecureRandom.uuid
@user = User.new(first_name: params[:user][:first_name], last_name: params[:user][:last_name], telephone: params[:user][:telephone], account_asso_id: params[:user][:account_asso_id], email: params[:user][:email], status: params[:user][:status], password: password, password_confirmation: password, invitation_token: invitation_token, invitation_created_at: Time.now, role: "asso")
end
def set_offices_access
if params[:office_access].first == "all"
@offices = account_asso.offices
else
@offices = Office.where(id: params[:office_access])
end
end
def save_user_and_send_invitation_email
if @user.save && @user.offices << offices
if UserMailer.send_invitation(@user, params[:app_base_url]).deliver_now
@user.invitation_sent_at = Time.now
if @user.save
render_success("mail_sent")
else
render_error("db")
end
else
render_error("mail_processing")
end
else
render_error("db")
end
end
def update_user_and_offices_access
@offices = Office.where(id: params[:office_access])
if @user_to_update.offices.destroy_all
if @user_to_update.offices << @offices
if @user_to_update.update(user_params)
render json: {message: "User successfully updated"}
else
render_error("db")
end
else
render("db")
end
else
render_error("db")
end
end
def set_user
@user = User.find(params[:id])
end
def set_account_asso
if params[:account_asso_id]
@account_asso = AccountAsso.find(params[:account_asso_id])
elsif params[:user][:account_asso_id]
@account_asso = AccountAsso.find(params[:user][:account_asso_id])
end
end
def user_params
params.require(:user).permit(
:email,
:account_id,
:first_name,
:last_name,
:telephone,
:position,
:status,
:user_id
)
end
def render_error(error_type)
case error_type
when "not_admin"
render json: {error: "You are not allowed to create a user for this account"}
when "mail_exists"
render json: {error: "Please fill the email field and try again"}
when "empty_email"
render json: {error: "Please fill the email field and try again"}
when "mail_processing"
render json: { error: "We couldnt send an email to your invitee. Please try again" }
when "db"
render json: {error: "An error occured. Please try again"}
when "unauthorized"
render json: {error: "Unauthorized"}
else
render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity
end
end
def render_success(success_type)
case success_type
when "mail_sent"
render json: { success: "An email was sent to your collaborator asking him to join your Quickbed team." }
when "password_changed"
render json: {success: "Your password was successfully changed"}
when "updated"
render json: {success: "Your infos were successfully updated"}
end
end
end
也许我应该改写链接到酒店概念的usersController
或者我应该创建第三个superusersController
,其中usersController链接到酒店的概念和usersController链接到概念协会会继承吗?你能帮我找到最合适的情况吗?
答案 0 :(得分:1)
您可以查看服务对象。它们只是普通的旧Ruby对象。您可以将invite
方法提取为类似UsersService#invite
的方法,然后从两个控制器中调用它。逻辑上的差异可以通过向它传递一个参数来处理(在用户或关联中运行的上下文)