从两个数据源创建哈希的最优雅方式
Most elegant way to create hash from two datasource
我有 building_table 和 api::building_table,我想默认使用 building_table 中的数据,但如果 building_table 中不存在这些数据我想在 api::building_table 获得它。
问题是有些属性可能不存在于 building_table 中,但存在于 api building_table 中。每个 table.
中也有不同名称的列
这是我的示例代码
def get_building_info
building = Building.find_by(id: params[:id])
api_building = Api::Building.find_by(id: params[:id])
building_hash = {}
building_hash[:name] = building.name || api_building.name
building_hash[:room] = building.room || api_building.room
building_hash[:rent] = building.rent || api_building.monthly_fee
...
end
有没有更优雅的方式来做到这一点?顺便说一句,这是在我的控制器中。
可能存在许多解决方案来实现这一点,但是,这里有一个更简单的解决方案:
def get_building_info
building = Hash.new
building[:name], building[:room] = desired_building.name, desired_building.room
end
private
def desired_building
Building.find_by(id: params[:id]) ||
Api::Building.find_by(id: params[:id])
end
我认为您的做法是正确的,但是 building
变量将被覆盖,您需要定义一个新变量,例如
building2 = {}
before_action :find_records, only: :get_building_info
def get_building_info
building_hash = {}
building_hash[:name] = building_name
building_hash[:room] = building_room
# OR
building_hash[:name], building_hash[:room] = building_name, building_room
end
private
def find_records
@building = Building.find_by(id: params[:id])
@api_building = Api::Building.find_by(id: params[:id])
end
def building_name
@building.name || @api_building.name
end
def building_room
@building.room || @api_building.room
end
通用方法,接受键列表作为参数:
def get_building_info(keys = %i[name room rent].zip(%i[name room fee]))
building = Building.find_by(id: params[:id])
api_building = Api::Building.find_by(id: params[:id])
keys.map do |key, api_key|
[
key,
building.attributes[key.to_s] || api_building.attributes[api_key.to_s]
]
end.to_h
end
你可以使用 Enumerable#each_with_object:
attrs = [ %i[name name], %i[room room], %i[rent monthly_fee] ]
attrs.each_with_object({}) do |(name, alias_name), h|
h[name] = building[name] || api_building[alias_name]
end
我有 building_table 和 api::building_table,我想默认使用 building_table 中的数据,但如果 building_table 中不存在这些数据我想在 api::building_table 获得它。 问题是有些属性可能不存在于 building_table 中,但存在于 api building_table 中。每个 table.
中也有不同名称的列这是我的示例代码
def get_building_info
building = Building.find_by(id: params[:id])
api_building = Api::Building.find_by(id: params[:id])
building_hash = {}
building_hash[:name] = building.name || api_building.name
building_hash[:room] = building.room || api_building.room
building_hash[:rent] = building.rent || api_building.monthly_fee
...
end
有没有更优雅的方式来做到这一点?顺便说一句,这是在我的控制器中。
可能存在许多解决方案来实现这一点,但是,这里有一个更简单的解决方案:
def get_building_info
building = Hash.new
building[:name], building[:room] = desired_building.name, desired_building.room
end
private
def desired_building
Building.find_by(id: params[:id]) ||
Api::Building.find_by(id: params[:id])
end
我认为您的做法是正确的,但是 building
变量将被覆盖,您需要定义一个新变量,例如
building2 = {}
before_action :find_records, only: :get_building_info
def get_building_info
building_hash = {}
building_hash[:name] = building_name
building_hash[:room] = building_room
# OR
building_hash[:name], building_hash[:room] = building_name, building_room
end
private
def find_records
@building = Building.find_by(id: params[:id])
@api_building = Api::Building.find_by(id: params[:id])
end
def building_name
@building.name || @api_building.name
end
def building_room
@building.room || @api_building.room
end
通用方法,接受键列表作为参数:
def get_building_info(keys = %i[name room rent].zip(%i[name room fee]))
building = Building.find_by(id: params[:id])
api_building = Api::Building.find_by(id: params[:id])
keys.map do |key, api_key|
[
key,
building.attributes[key.to_s] || api_building.attributes[api_key.to_s]
]
end.to_h
end
你可以使用 Enumerable#each_with_object:
attrs = [ %i[name name], %i[room room], %i[rent monthly_fee] ]
attrs.each_with_object({}) do |(name, alias_name), h|
h[name] = building[name] || api_building[alias_name]
end