我想公开我的数据库ID并使用routes helper对id进行编码/解码。对于编码,我使用Hashids gem。
现在我有:
的routes.rb
get 'companies/:id/:year', to: 'company#show', as: 'companies'
公司网址:
/companies/1/2015
对于id编码,我有编码/解码辅助方法:
def encode(id)
# encode...
return 'ABC123'
end
def decode(hashid)
# decode...
return 1
end
我如何实现,id将与路由助手转换? 所以必须显示URL:
/companies/ABC123/2015
并且控制器必须自动获取id为1的参数。
答案 0 :(得分:2)
感谢您的回答!但我不会在没有模型或控制器变化的情况下解码params id。经过长时间的考虑,我已经决定在控制器获得params之前操纵params id。我在路线约束中操纵参数。
encoding_helper.rb
module EncodingHelper
def encode(id)
# encode...
return 'ABC123'
end
def decode(hashid)
# decode...
return 1
end
end
companies_path(id: encode(1), year: 2015) # => /companies/ABC123/2015
LIB /约束/ decode_company_id.rb
module Constraints
class DecodeId
extend EncodingHelper
def self.matches?(request)
request.params['id'] = decode(request.params['id']).to_s if request.params['id'].present?
true
end
end
end
配置/ routes.rb中
constraints(Constraints::DecodeId) do
get 'companies/:id/:year', to: 'company#show', as: 'companies'
end
使用约束解码params id并且在控制器中没有操作时,params id为1。
答案 1 :(得分:1)
您可以使用to_param方法。
#in Company
def to_param
self.encoded_id
end
def encoded_id
self.class.encode_id(self.id)
end
def find_by_encoded_id(encoded_id)
self.find_by_id(self.class.decode_id(encoded_id)
end
#class methods
class << self
def encode_id(id)
#encoding algorithm here
end
def decode_id(encoded_id)
#decoding algorithm here
end
end
这将意味着具有公司ID的网址实际上将使用encoded_id,假设您将公司对象传递给路径助手,例如company_path(@company)
。
然后,在您的公司控制器中,您只需要确保find_by_encoded_id(params[:id])
而不是find_by_id(params[:id])
。
答案 2 :(得分:0)
Rails路由器不应该进行任何解码:
The Rails router recognizes URLs and dispatches them to a controller's action.
逻辑应该属于控制器。
答案 3 :(得分:0)
当您的控制器收到编码的响应时:
#Appropriate controller
def show
Company.decode(params[:id])
end
如果您将模型方法稍微调整为:
,这项工作很有效def self.decode(code)
# decode => get id
find(id) #returns Company object
end
答案 4 :(得分:0)
你可以试试这个。友好id的自定义方法
在模型中
extend FriendlyId
friendly_id :decode
# Try building a slug based on the following fields in
# increasing order of specificity.
def decode
conditional_check(self.id)
end
private
def conditional_check(id)
return "ABC123" if id == 1
end