在 Rails 5 资源的显示操作中创建自定义 URL
Creating a custom URL in Rails 5 Resource's show action
鉴于资源事件,我希望 /events/1
在输入时导航到 URL 栏中的 /events/1/column_name
。列名是事件数据库迁移中的 t.string :name
。此 column_name 需要在重定向前调用 parameterize
。关于如何完成这项工作有什么想法吗?
示例:
如果您在加载后导航到 https://whosebug.com/users/4180797 the URL will automatically become https://whosebug.com/users/4180797/james-lowrey。适用于 4180797/any-other-txt-here
。所以 "James Lowrey" 将是 name
列,在调用 parameterize
后它将变为 james-lowrey
。
好吧,这真的很难弄清楚,甚至不知道我以前可以访问很多这些变量。
首先编辑您的 config/routes.rb
以接受 id/other_stuff
Rails.application.routes.draw do
resources :events
get "/events/:id/*other" => "events#show" #if any txt is trailing id, also send this route to events#show
end
如果 URL 不正确,下一步修改 event_controller.show
以重定向。
def show
#redirect if :name is not seen in the URL
if request.format.html?
name_param = @event.name.parameterize
url = request.original_url
id_end_indx = url.index(@event.id.to_s) + (@event.id.to_s).length + 1 #+1 for '/' character
##all URL txt after id does not match name.parameterize
if url[id_end_indx..-1] != @event.name.parameterize
redirect_to "/events/#{@event.id}/#{name_param}"
end
end
end
这将导致与问题中 Stack Overflow 示例完全相同的行为。
另一种选择是将 pushState
与 javascript/jquery 结合使用,例如:
首先在show.html.erb
中添加如下script
<script>
$(document).ready(function() {
history.pushState(null, null, "/events/<%= @event.id %>/<%= @event.name.parameterize %>");
});
</script>
这将改变每次加载时的 url,无论 /:id
之后发生什么。
其次,修改路由以接受 /:id
之后的任何内容(并忽略它):
Rails.application.routes.draw do
#...
get "/events/:id/*other" => "events#show"
end
如果 /:id
之后的任何文本不匹配,此选项还有避免重定向的额外好处,它将只获取 id
并将其后的任何其他文本替换为 @event.name.parameterize
在 url(没有任何重新加载)。
鉴于资源事件,我希望 /events/1
在输入时导航到 URL 栏中的 /events/1/column_name
。列名是事件数据库迁移中的 t.string :name
。此 column_name 需要在重定向前调用 parameterize
。关于如何完成这项工作有什么想法吗?
示例:
如果您在加载后导航到 https://whosebug.com/users/4180797 the URL will automatically become https://whosebug.com/users/4180797/james-lowrey。适用于 4180797/any-other-txt-here
。所以 "James Lowrey" 将是 name
列,在调用 parameterize
后它将变为 james-lowrey
。
好吧,这真的很难弄清楚,甚至不知道我以前可以访问很多这些变量。
首先编辑您的 config/routes.rb
以接受 id/other_stuff
Rails.application.routes.draw do
resources :events
get "/events/:id/*other" => "events#show" #if any txt is trailing id, also send this route to events#show
end
如果 URL 不正确,下一步修改 event_controller.show
以重定向。
def show
#redirect if :name is not seen in the URL
if request.format.html?
name_param = @event.name.parameterize
url = request.original_url
id_end_indx = url.index(@event.id.to_s) + (@event.id.to_s).length + 1 #+1 for '/' character
##all URL txt after id does not match name.parameterize
if url[id_end_indx..-1] != @event.name.parameterize
redirect_to "/events/#{@event.id}/#{name_param}"
end
end
end
这将导致与问题中 Stack Overflow 示例完全相同的行为。
另一种选择是将 pushState
与 javascript/jquery 结合使用,例如:
首先在show.html.erb
script
<script>
$(document).ready(function() {
history.pushState(null, null, "/events/<%= @event.id %>/<%= @event.name.parameterize %>");
});
</script>
这将改变每次加载时的 url,无论 /:id
之后发生什么。
其次,修改路由以接受 /:id
之后的任何内容(并忽略它):
Rails.application.routes.draw do
#...
get "/events/:id/*other" => "events#show"
end
如果 /:id
之后的任何文本不匹配,此选项还有避免重定向的额外好处,它将只获取 id
并将其后的任何其他文本替换为 @event.name.parameterize
在 url(没有任何重新加载)。