Ruby on rails Rails 4仅带有查询字符串或数字的路由约束

Ruby on rails Rails 4仅带有查询字符串或数字的路由约束,ruby-on-rails,ruby,rest,ruby-on-rails-4,routes,Ruby On Rails,Ruby,Rest,Ruby On Rails 4,Routes,我正试图在限制条件下实现这两条路线: 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=ju

我正试图在限制条件下实现这两条路线:

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
触发

不起作用,我在谷歌上搜索了很多关于这个问题的信息,但我似乎找到了第二或第三版本RubyonRails的解决方案,其中大多数现在都被弃用了


有什么想法吗?谢谢。

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

所以
get“products/:name”,to:“products#search”,约束:{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

如果您喜欢结果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
您可能希望通过返回nil对
find\u执行一些错误检查,因为
:name
与任何内容都不匹配,但基本上就是这样

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

get "products/:id", to: "products#show", constraints: { id: /[[:digit]]/ }
get "products/:name", to: "products#search", constraints: { name: /[[:alpha:]]/ }
您的应用程序应响应以下两个方面:

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

我感觉regex匹配在路由上可能有点不同-我认为它每次都锚定到参数的开始和结束


记住这一点,您的正则表达式每个匹配一个字符。请尝试使用
id://\d+/
name://.*\d.*/
来代替。

只需指定一条不同的路线可能会更容易、更容易:

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

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

,如前所述,您的第二条路径将响应如下内容:
localhost:3000/products/juice
。这就是您想要的吗?它确实会响应
localhost:3000/products/juice
,问题是我必须使用查询字符串来获取name参数,而不是id参数。我正在寻找一种路由可以根据URL中是否有数字或名称做出响应的方法。无需使用查询字符串来获取
name
的值。我将展开回答。它似乎也不起作用。我正在寻找一种路由可以根据URL中是否有数字或名称做出响应的方法,例如,如果有一个数字作为参数,则使用该数字作为id执行show操作,否则,使用查询字符串中传递的name参数执行搜索操作。无论如何,我感谢您的回复。
get”/products?name=:name“,to:“products#search”,约束:{name:/[a-zA-Z]/}
。因为
get“products/:id”
get“products/:name”
是相同的。您应该设计并指定要处理的搜索url。您不会在路由中的
之后指定参数。参数的不同约束应该告诉他们应该遵循哪一个。。。因此在
routes.rb
文件中,它应该有:
get“products/:name”,to:“products#search”
get“products/:id”,to:“products#show”
,对吗?它返回这个错误
Regexp锚字符在路由要求中是不允许的:/^[a-zA-Z]/
但根据@PJSCopeland answer,我移除了锚,并在正则表达式的最后添加了加号。现在效果很好!非常感谢。很抱歉,请删除“^”。我在之前的编辑中塞满了东西。我使用的一个旧应用程序有
[a-zA-Z.0-9_ \-]
,而不是简单的
——你可能必须使用它。从路由指南中:“:约束采用正则表达式,但限制不能使用regexp锚”“但是,请注意,您不需要使用锚定,因为所有管线都在起点锚定。“.它们不是锚定在最后,只是开始。啊,对了。我最后一次使用它们是在几年前,所以我一定已经忘记了。然后,Cat再次表示,它只需将
+
放在末尾就可以了,如果它没有锚定到末尾,肯定不会有什么不同。。。?