重构可选参数方法以删除“if”语句
Refactor optional parameters method to remove `if` statements
我有一个方法 select_active_buildings
,其中三个参数默认为 nil
,以使用提供的信息过滤我的数据库。
def select_active_buildings(category:nil, upgrader:nil, upgrade_resource:nil)
my_active_buildings = self.buildings.active(self.townhall_level)
if category && upgrader && upgrade_resource
return my_active_buildings.where(category:category, upgrader:upgrader, upgrade_resource:upgrade_resource)
elsif category && upgrader
return my_active_buildings.where(category:category, upgrader:upgrader)
elsif category && upgrade_resource
return my_active_buildings.where(category:category, upgrade_resource:upgrade_resource)
elsif upgrader && upgrade_resource
return my_active_buildings.where(upgrader:upgrader, upgrade_resource:upgrade_resource)
elsif category
return my_active_buildings.where(category:category)
elsif upgrader
return my_active_buildings.where(upgrader:upgrader)
elsif upgrade_resource
return my_active_buildings.where(upgrade_resource:upgrade_resource)
else
return my_active_buildings
end
end
我需要帮助重构这个方法。
我会这样做:
def select_active_buildings(category: nil, upgrader: nil, upgrade_resource: nil)
my_active_buildings = self.buildings.active(self.townhall_level)
cond = {
category: category,
upgrader: upgrader,
upgrade_resource: upgrade_resource
}.select { |k, v| v }
my_active_buildings.where(cond)
end
或者,
def select_active_buildings(category: nil, upgrader: nil, upgrade_resource: nil)
my_active_buildings = self.buildings.active(self.townhall_level)
cond = {}
cond[:category] = category if category
cond[:upgrader] = upgrader if upgrader
cond[:upgrade_resource] = upgrade_resource if upgrade_resource
my_active_buildings.where(cond)
end
或者,如果我真的不关心 select_active_function
级别的语法检查,
def select_active_buildings(cond)
my_active_buildings = self.buildings.active(self.townhall_level)
my_active_buildings.where(cond)
end
如果你真的不想要 .where({})
大小写,你可以在它前面加上 return my_active_buildings if cond.empty?
。
假设您正在使用 ActiveRecord、Mongoid 或其他具有可链接 where
的东西,您可以利用以下事实:
o.where(:a => b, :c => d)
等同于:
o.where(:a => b).where(:c => d)
这让你可以这样做:
def select_active_buildings(category: nil, upgrader: nil, upgrade_resource: nil)
buildings = self.buildings.active(self.townhall_level)
buildings = buildings.where(category: category) if(category)
buildings = buildings.where(upgrader: upgrader) if(upgrader)
buildings = buildings.where(upgrade_resource: upgrade_resource) if(upgrade_resource)
buildings
end
甚至:
def select_active_buildings(conditions)
buildings = self.buildings.active(self.townhall_level)
%i[category upgrader upgrade_resource]
.select { |f| conditions.has_key?(f) }
.inject(buildings) { |q, f| q.where(f => conditions[f]) }
end
def select_active_buildings(category: nil, upgrader: nil, upgrade_resource: nil)
buildings.active(self.townhall_level).where(
**({category: category} if category).to_h,
**({upgrader: upgrader} if upgrader).to_h,
**({upgrade_resource: upgrade_resource} if upgrade_resource).to_h,
)
end
我有一个方法 select_active_buildings
,其中三个参数默认为 nil
,以使用提供的信息过滤我的数据库。
def select_active_buildings(category:nil, upgrader:nil, upgrade_resource:nil)
my_active_buildings = self.buildings.active(self.townhall_level)
if category && upgrader && upgrade_resource
return my_active_buildings.where(category:category, upgrader:upgrader, upgrade_resource:upgrade_resource)
elsif category && upgrader
return my_active_buildings.where(category:category, upgrader:upgrader)
elsif category && upgrade_resource
return my_active_buildings.where(category:category, upgrade_resource:upgrade_resource)
elsif upgrader && upgrade_resource
return my_active_buildings.where(upgrader:upgrader, upgrade_resource:upgrade_resource)
elsif category
return my_active_buildings.where(category:category)
elsif upgrader
return my_active_buildings.where(upgrader:upgrader)
elsif upgrade_resource
return my_active_buildings.where(upgrade_resource:upgrade_resource)
else
return my_active_buildings
end
end
我需要帮助重构这个方法。
我会这样做:
def select_active_buildings(category: nil, upgrader: nil, upgrade_resource: nil)
my_active_buildings = self.buildings.active(self.townhall_level)
cond = {
category: category,
upgrader: upgrader,
upgrade_resource: upgrade_resource
}.select { |k, v| v }
my_active_buildings.where(cond)
end
或者,
def select_active_buildings(category: nil, upgrader: nil, upgrade_resource: nil)
my_active_buildings = self.buildings.active(self.townhall_level)
cond = {}
cond[:category] = category if category
cond[:upgrader] = upgrader if upgrader
cond[:upgrade_resource] = upgrade_resource if upgrade_resource
my_active_buildings.where(cond)
end
或者,如果我真的不关心 select_active_function
级别的语法检查,
def select_active_buildings(cond)
my_active_buildings = self.buildings.active(self.townhall_level)
my_active_buildings.where(cond)
end
如果你真的不想要 .where({})
大小写,你可以在它前面加上 return my_active_buildings if cond.empty?
。
假设您正在使用 ActiveRecord、Mongoid 或其他具有可链接 where
的东西,您可以利用以下事实:
o.where(:a => b, :c => d)
等同于:
o.where(:a => b).where(:c => d)
这让你可以这样做:
def select_active_buildings(category: nil, upgrader: nil, upgrade_resource: nil)
buildings = self.buildings.active(self.townhall_level)
buildings = buildings.where(category: category) if(category)
buildings = buildings.where(upgrader: upgrader) if(upgrader)
buildings = buildings.where(upgrade_resource: upgrade_resource) if(upgrade_resource)
buildings
end
甚至:
def select_active_buildings(conditions)
buildings = self.buildings.active(self.townhall_level)
%i[category upgrader upgrade_resource]
.select { |f| conditions.has_key?(f) }
.inject(buildings) { |q, f| q.where(f => conditions[f]) }
end
def select_active_buildings(category: nil, upgrader: nil, upgrade_resource: nil)
buildings.active(self.townhall_level).where(
**({category: category} if category).to_h,
**({upgrader: upgrader} if upgrader).to_h,
**({upgrade_resource: upgrade_resource} if upgrade_resource).to_h,
)
end