我的控制器中有索引操作:
def index
authenticate_admin!
@users = User.paginate(per_page: 25, page: params[:page])
if params[:list_type].to_i == 2 # => Pending mentors
@users = @users.where(documents: { is_verified: 0 }, user_type: 0, profile_status: 1)
elsif params[:list_type].to_i == 1 # => approved listing
@users = @users.where(documents: { is_verified: 1 }, user_type: 0) if params[:user_type].to_i.zero? # => Mentor
@users = @users.where(user_type: 1) if params[:user_type].to_i == 1 # => mentee
end
@users = @users.where('full_name LIKE ?', "%#{params[:search]}%") if params[:search].present?
@users = if params[:sort].to_i == 1
@users.order(full_name: :asc)
else
@users.order(id: :desc)
end
@users = @users.profession.where(id: params[:profession_ids]) if params[:profession_ids].present?
@users = @users.call('age >= ?', params[:from_date]) if params[:from_date].present?
@users = @users.call('age <= ?', params[:to_date]) if params[:to_date].present?
@users = @users.where(gender: params[:gender]) if params[:gender].present?
@users = @users.includes(:document)
end
但是当我运行Rubocop
来检查我的代码是否包含任何offense
时。
然后返回两个错误。
app/controllers/users_controller.rb:5:3: C: Metrics/CyclomaticComplexity: Cyclomatic complexity for index is too high. [11/6]
def index ...
^^^^^^^^^
app/controllers/users_controller.rb:5:3: C: Metrics/PerceivedComplexity: Perceived complexity for index is too high. [13/7]
def index ...
^^^^^^^^^
因此,我将索引操作分为多个操作,例如:
def index
authenticate_admin!
@users = User.paginate(per_page: 25, page: params[:page])
if params[:list_type].to_i == 2 # => Pending mentors
@users = @users.where(documents: { is_verified: 0 }, user_type: 0, profile_status: 1)
elsif params[:list_type].to_i == 1 # => approved listing
@users = @users.where(documents: { is_verified: 1 }, user_type: 0) if params[:user_type].to_i.zero? # => Mentor
@users = @users.where(user_type: 1) if params[:user_type].to_i == 1 # => mentee
end
search
end
def search
@users = @users.where('full_name LIKE ?', "%#{params[:search]}%") if params[:search].present?
@users = if params[:sort].to_i == 1
@users.order(full_name: :asc)
else
@users.order(id: :desc)
end
apply_filter
end
def apply_filter
@users = @users.profession.where(id: params[:profession_ids]) if params[:profession_ids].present?
@users = @users.call('age >= ?', params[:from_date]) if params[:from_date].present?
@users = @users.call('age <= ?', params[:to_date]) if params[:to_date].present?
@users = @users.where(gender: params[:gender]) if params[:gender].present?
@users = @users.includes(:document)
end
这是实现这样的代码的正确方法,还是我可以做些其他事情来完善我的编码结构?
答案 0 :(得分:3)
这是实现这样的代码的正确方法
只要您发现代码合理清晰即可。如果index
方法是控制器中唯一的方法,那么导航用户搜索的逻辑将不是问题。
还有什么我可以做的事情来完善我的编码结构
选项之一是将这两种方法(甚至更多的逻辑)提取到单独的类/文件中。例如,类似:
控制器
def index
authenticate_admin!
@users = User.paginate(per_page: 25, page: params[:page])
if params[:list_type].to_i == 2 # => Pending mentors
@users = @users.where(documents: { is_verified: 0 }, user_type: 0, profile_status: 1)
elsif params[:list_type].to_i == 1 # => approved listing
@users = @users.where(documents: { is_verified: 1 }, user_type: 0) if params[:user_type].to_i.zero? # => Mentor
@users = @users.where(user_type: 1) if params[:user_type].to_i == 1 # => mentee
end
@users = Users::Search.new(@users).call
end
服务
class Users::Search
attr_reader :params, :users
def initialize(users, params)
@users = users
@params = params
end
def search
users = @users.where('full_name LIKE ?', "%#{params[:search]}%") if params[:search].present?
users = if params[:sort].to_i == 1
users.order(full_name: :asc)
else
users.order(id: :desc)
end
apply_filter(users)
end
def apply_filter(users)
users = users.profession.where(id: params[:profession_ids]) if params[:profession_ids].present?
users = users.call('age >= ?', params[:from_date]) if params[:from_date].present?
users = users.call('age <= ?', params[:to_date]) if params[:to_date].present?
users = users.where(gender: params[:gender]) if params[:gender].present?
users.includes(:document)
end
end
提取的优点之一是,此类类比控制器方法更容易测试,而控制器方法需要针对每个测试用例进行请求并解析响应。