Rails 4路由约束仅包含查询字符串或数字

我正在尝试使用约束来实现这两个路由:

get "products/:id", to: "products#show", constraints: { id: /\d/ } get "products/:name", to: "products#search", constraints: { name: /[a-zA-Z]/ } 

第一个路由应使用localhost:3000/products/3等URL触发,最后一个路径应使用localhost:3000/products/?name=juice触发。

不起作用,我搜索了很多关于这个问题,但我似乎找到了Ruby on Rails的第二个或第三个版本的解决方案,现在大多数都被弃用了。

有任何想法吗? 谢谢。

如果您喜欢结果URL的外观,可以按原样使用路由。 不需要查询字符串。

在你的控制器中,你会有以下几点:

 def show @product = Product.find(params[:id]) # do stuff end def search # I'm assuming your Product model has a `name` attribute @product = Product.find_by(name: params[:name]) # do stuff end 

你可能想要对find_by返回nil进行一些错误检查,因为:name与任何东西都不匹配,但基本上就是这样。

您的routes.rb将具有您的原始路由定义:

 get "products/:id", to: "products#show", constraints: { id: /[[:digit]]/ } get "products/:name", to: "products#search", constraints: { name: /[[:alpha:]]/ } 

您的申请应该同时响应:

  • 本地主机:3000 /产品/ 3
  • 本地主机:3000 /产品/果汁

首先你必须知道查询字符串和url是什么。 localhost:3000/products/3这是url,三是符号:id时使用问号localhost:3000/products/3?name=juice ,name = juice是查询字符串。

所以get "products/:name", to: "products#search", constraints: { name: /[a-zA-Z]/ }你应该在下面替换

 get "products/:id?name=:name", to: "products#search", constraints: { id: /\d/, name: /[a-zA-Z]/ } 

例如:localhost:3000 / products / 3?name = xxxxx

我有一种感觉,正则表达式匹配在路线上可能会略有不同 – 我认为它每次都会锚定参数的开始和结束。

考虑到这一点,你的正则表达式每个都匹配一个字符。 请尝试id: /\d+/name: /.*\D.*/ id: /\d+/

指定不同的路径可能更简单,更Railsy:

 get "products/:id", to: "products#show" get "products/search/:name", to: "products#search" 

或者,只需将您的products#index params[:q] action handle params[:q]作为搜索字符串,这也很常见。 然后您的url将是www.example.com/products?q=juice