假设我的一个名为Company的模型中有以下哈希值。
FIELDS = {
TEAM: {
'num_founders': 'Number of Founders',
'num_employees': 'Number of Employees',
'founders': {
'person_info': {
'full_name': 'Full Name',
'first_name': 'First Name',
'last_name': 'Last Name',
'location': 'Location',
'gender': 'Gender',
'biography': 'Biography',
'num_articles': 'Number of Articles'
}
}
}
}
我在我的应用程序控制器中有一个动作,它将此哈希呈现为json:
def field_names
module_name = params[:module]
category = params[:category]
case module_name
when 'company'
render json: Company::FIELDS[category.to_sym].to_json
end
end
所以现在如果我打开localhost:3000/field_names/company/TEAM
,我就会得到json。但我现在面临的问题是我需要得到这个哈希的子哈希。就像我想要/field_names/company/TEAM/founders/person_info
并获得相应的对象一样。
首先,我用斜杠拆分网址以获取密钥。我无法弄清楚如何使用这些字符串来访问哈希值。
如果我定义路线,如get '/field_names/:query', to: 'application#field_names
如果我点击localhost:3000/field_names/company/TEAM/founders
该操作应该呈现Company::FIELDS[:TEAM]["founders"]
对象,这将是
'person_info': {
'full_name': 'Full Name',
'first_name': 'First Name',
'last_name': 'Last Name',
'location': 'Location',
'gender': 'Gender',
'biography': 'Biography',
'num_articles': 'Number of Articles'
}
为此,我的行动应该是这样的:
def field_names
query = params[:query]
keys = query.split("/")
#keys.first::FIELDS[key2][key3]... .to_json
end
我如何实现这一目标?谢谢:))
答案 0 :(得分:1)
这是您项目中的路由问题。实际上,您应该有一条路径来检索这些字段名,例如:
get 'field_names' => 'controller#action'
然后,您可以在您的网址上传递任何参数。 例如
/field_names?company=TEAM&attribute=founders
然后,这些属性将在您的控制器中显示为
params[:company]
params[:attribute]
所以你只能渲染你想要的属性
答案 1 :(得分:1)
这样的事情怎么样:
fields = {
TEAM: {
'num_founders': 'Number of Founders',
'num_employees': 'Number of Employees',
'founders': {
'person_info': {
'full_name': 'Full Name',
'first_name': 'First Name',
'last_name': 'Last Name',
'location': 'Location',
'gender': 'Gender',
'biography': 'Biography',
'num_articles': 'Number of Articles'
}
}
}
}.with_indifferent_access
'TEAM/founders'.split('/').each do |key|
fields = fields[key]
end
puts fields
=> {"person_info"=>{"full_name"=>"Full Name", "first_name"=>"First Name", "last_name"=>"Last Name", "location"=>"Location", "gender"=>"Gender", "biography"=>"Biography", "num_articles"=>"Number of Articles"}}
仅用于控制台,我将FIELDS
更改为fields
(SHOUTING_CASE通常保留用于常量,fwiw)。而且,我使用with_indifferent_access
因为您的嵌套哈希值使用strings
和symbols
作为键。
如果你想要person_info
,那么:
fields = {
TEAM: {
'num_founders': 'Number of Founders',
'num_employees': 'Number of Employees',
'founders': {
'person_info': {
'full_name': 'Full Name',
'first_name': 'First Name',
'last_name': 'Last Name',
'location': 'Location',
'gender': 'Gender',
'biography': 'Biography',
'num_articles': 'Number of Articles'
}
}
}
}.with_indifferent_access
'TEAM/founders/person_info'.split('/').each do |key|
fields = fields[key]
end
puts fields
=> {"full_name"=>"Full Name", "first_name"=>"First Name", "last_name"=>"Last Name", "location"=>"Location", "gender"=>"Gender", "biography"=>"Biography", "num_articles"=>"Number of Articles"}
如果网址格式错误,您可能需要在其中添加一些try
。
此外,您可以在任何地方抽象和简化该位:
case module_name
when 'company'
render json: Company::FIELDS[category.to_sym].to_json
end
假设你有(routes.rb
):
get '/field_names/:query'
你点击了:
localhost:3000/field_names/company/TEAM/founders
那么你的参数应包括:
{query: 'company/TEAM/founders'}
在这种情况下,您可以执行以下操作:
def field_names
query_split = params[:query].split
module_name = query_split.shift.camelize
fields = "#{module_name}::FIELDS".constantize.clone.with_indifferent_access
query_split.each{|key| fields = fields[key]}
render json: fields
end
您不必将to_json
放在哈希的末尾,顺便说一句。