我在我的应用to_param
中使用来创建自定义网址(此自定义路径包含斜杠):
class Machine < ActiveRecord::Base
def to_param
MachinePrettyPath.show_path(self, cut_model_text: true)
end
end
问题是,由于Rails 4.1.2
行为已更改且Rails不允许在URL中使用斜杠(使用自定义URL时),因此它会转义斜杠。
我有这样的路线:
Rails.application.routes.draw do
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
resources :machines, except: :destroy do
collection do
get :search
get 'search/:ad_type(/:machine_type(/:machine_subtype(/:brand)))', action: 'search', as: :pretty_search
get ':subcategory/:brand(/:model)/:id', action: 'show', as: :pretty
patch ':subcategory/:brand(/:model)/:id', action: 'update' # To be able to update machines with new rich paths.
end
end
end
end
我尝试by recommendation in the thread只为show方法使用glob param以确保它有效:
resources :machines, except: :destroy do
#...
end
scope format: false do
get '/machines/*id', to: "machines#show"
end
但它绝对不起作用。我仍然有这样破碎的链接:
http://localhost:3000/machines/tractor%2Fminitractor%2Fmodel1%2F405
当然,如果我替换自己的转义斜杠:
http://localhost:3000/machines/tractor/minitractor/model1/405
尝试访问路径,然后打开页面。
任何想法我该如何解决?
答案 0 :(得分:1)
使用自动生成的网址助手时,我遇到了同样的问题。我使用调试器跟踪新行为的源(在ActionDispatch :: Journey :: Visitors :: Formatter附近),但没有找到任何有希望的解决方案。看起来参数化模型现在被严格地视为路径的单个斜线分隔段并相应地进行转义,否则没有选项告诉格式化程序。
据我所知,获取url helper以产生旧结果的唯一方法是使用原始路由文件并分别传递每个段,如:
pretty_machine_path(machine.subcategory, machine.brand, machine.model, machine.id)
这很丑陋,显然不是你想要一遍又一遍地做的事情。您可以向MachinePrettyPath添加一个方法,将这些段生成为一个数组,然后展开帮助器的结果(比如pretty_machine_path(*MachinePrettyPath.show_path_segments(machine))
),但这仍然非常详细。
在上述令人头疼的问题和“你做错了”之间。您链接到的Rails票证中的开发人员的态度,对我来说最简单的选择是咬紧牙关并编写自定义URL助手而不是使用to_param。我还没有找到一个好的例子&#34;对&#34;做到这一点的方法,但像这个简单的例子应该达到目的:
#app/helpers/urls_helper.rb
module UrlsHelper
def machine_path(machine, options = {})
pretty_machine_path(*MachinePrettyPath.show_path_segments(machine), options)
end
end
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
helper :urls #for the views
include UrlsHelper #for controllers
#...
end
答案 1 :(得分:0)
如果您确定返回的网址是安全的,则应将.html_safe添加到返回的字符串中:
MachinePrettyPath.show_path(self, cut_model_text: true).html_safe
(没有看到可以转义的其他任何地方,但检查你的应用中的所有流量,也许通过方法手动测试方法)
答案 2 :(得分:0)
如何自己定义网址?
def to_param
"#{ subcategory.title.parameterize }/#{ brand.name.parameterize }/#{ model.name.parameterize) }/#{ id }"
end
然后在你的路线上这样:
get 'machines/*id', to: "machines#show"
当您在模型上进行查找时,您还必须拆分params [:id]。
Machine.find( params[:id].split("/").last )