将多个动作路由到同一控制器和动作

发布于 2024-11-19 06:15:04 字数 1066 浏览 5 评论 0原文

我正在尝试在我的 Rails 应用程序上实现类似的功能:

match '/:language', :to => 'posts#search_result'
match '/:tag', :to => 'posts#search_result'
match '/:language/:tag', :to => 'posts#search_result'

我正在使用此 search_result 操作根据语言和标签过滤一些帖子。

问题是有时 :tag 将为 nil 或 :language 将为 nil;所以我在调用操作时有这 3 种可能性:

<%=link_to "Spanish", {:controller => 'posts', :action => 'search_result', :language => "spanish"} %>

<%= link_to "Spanish", {:controller => 'posts', :action => 'search_result', :language => "spanish", :tag => @tag} %>

<%=link_to "#{tag.name}", {:controller => 'posts', :action => 'search_result', :tag => @tag} %>

我期望有这样的 URL:

/spanish          (for the first case)
/spanish/rails    (where rails is a tag, for the second case)
/rails            (for the third case)

但现在我得到了第一种和第三种情况的正确结果,但对于第二种情况我得到了: /spanish?tag=rails 或再次/西班牙语(取决于我是先选择标签还是先选择语言)。

我希望我的解释是正确的。有什么想法吗??谢谢!。

I am trying to get something like this working on my Rails app:

match '/:language', :to => 'posts#search_result'
match '/:tag', :to => 'posts#search_result'
match '/:language/:tag', :to => 'posts#search_result'

I am using this search_result action to filter some posts depending of the language and the tag.

The problem is that sometimes :tag will be nil or :language will be nil; so i have these 3 possibilities when calling the action:

<%=link_to "Spanish", {:controller => 'posts', :action => 'search_result', :language => "spanish"} %>

<%= link_to "Spanish", {:controller => 'posts', :action => 'search_result', :language => "spanish", :tag => @tag} %>

<%=link_to "#{tag.name}", {:controller => 'posts', :action => 'search_result', :tag => @tag} %>

And I am expection to have URLs like:

/spanish          (for the first case)
/spanish/rails    (where rails is a tag, for the second case)
/rails            (for the third case)

But right now i am getting the rigth thing for the first and third case, but for the second case i am getting:
/spanish?tag=rails
or again /spanish (depending on if i had selected a tag first or a language first).

I hope i explained myself right. Any idea??. thanks!.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷梦 2024-11-26 06:15:04

路由器无法区分 :language 和 :tag 之间的区别。

只是因为当您在视图中构建代码时,您的路线会显示“语言”和“标签”..请记住,在 html 中,这已被翻译成普通的 ole URL,例如 /spanish 或 /rails,

然后必须计算出路线从这个 URL 出来。

现在,正如我所说,路由器无法判断特定单词一种语言或标签......并且普通的 ole-URL 没有单词“标签”或“语言” " 不再在其中......所以你在这里的两个路由:

match '/:language', :to => 'posts#search_result'
match '/:tag', :to => 'posts#search_result'

都是相同类型的 URL

只是斜杠后面的一个标记。以下是一些匹配该路由的示例:

/greek
/spanish
/rails
/urdu
/whatever

它们将全部匹配第一个匹配“斜杠后的单个标记”的路由...这意味着您的路由器会将它们全部匹配到“ language” 路由,并且永远不会匹配“/:tag” 路由,因为它已经在上面的路由上匹配。

呵呵:这对路由器来说都是希腊语;)

编辑:

嗨,这对我理解路由的工作原理有很大帮助..但我仍然看不清楚。我明白你所说的,所以基本上我明白我应该做一些类似 match '/tags/:tag 的事情,至少只路由到 posts#search_result 以 /tag 开头的 URL。.. 解决方案是什么??

是的,“/tags/:tag”将是清晰且明确的,但如果您希望它在标签与语言方面真正灵活,那么简单的服务会更好:

match '/posts/search', :to => 'posts#search_result'

它可以使用上面的任何 link_to 示例来生成例如

/posts/search?tag=rails
/posts/search?language=spanish
/posts/search?language=spanish&tag=rails

:也更加清楚正在通过的内容和原因。

第三个 URL 的描述是“我正在搜索一组包含 language = 西班牙语且标签 = Rails 的帖子”。

您的 URL 应反映资源(在本例中是一组帖子) )其他一切最好作为查询参数完成。

The router cannot tell the difference between a :language and a :tag.

Just because your routes say "language" and "tag" when you are constructing your code in the view.. remember that in the html this has been translated into just plain ole URLs eg /spanish or /rails

the route then has to be figured out from this URL.

Now as I said, the router can't tell that a particular word is a language or a tag... and the plain-ole-URL doesn't have the word "tag" or "language" in it anymore... so your two routes here:

match '/:language', :to => 'posts#search_result'
match '/:tag', :to => 'posts#search_result'

are both the same kind of URL

Just a single token after the slash. Here are some examples that will match that route:

/greek
/spanish
/rails
/urdu
/whatever

They will all match the first route that matches on "a single token after a slash"... which means your router will match all of them to the "language" route and will never ever match the "/:tag" route, because it's already matched on the route above.

he he: it's all greek to the router ;)

Edit:

Hi, this is helping me a lot to understand how routing works.. but still i can't see it clear. I understand what you said, and so basically i understand i should do something like match '/tags/:tag to at least only route to posts#search_result the URLS starting by /tag .. what would be a solution??

yes, "/tags/:tag" would be clear and unambiguous, but if you want it to truly flexible in tag vs language you would be better served by the simple:

match '/posts/search', :to => 'posts#search_result'

which can use any of your link_to examples above to generate eg:

/posts/search?tag=rails
/posts/search?language=spanish
/posts/search?language=spanish&tag=rails

It's also far more clear what is being passed and why.

The description of the third URL is "I'm searching for a set of posts which have language = spanish and tag = rails"

Your URL should reflect the resource (which in this case is a set of posts) everything else is better done as query params.

凯凯我们等你回来 2024-11-26 06:15:04

不要单独定义 /:language 和 /:language/:tag,而是一起定义它们,并使用 /:tag 作为可选 URI 元素。

match '/:language(/:tag)', :to => 'posts#search_result'

我相信路由(以及从它们生成的 URI)按照定义路由的顺序进行匹配。您在定义 /:lang/:tag 之前定义了 /:lang,因此它匹配 /:lang 并使 :tag 成为 GET 参数。我想您可以优化定义的顺序,但我相信使用上述语法是首选方法。

Instead of defining /:language and /:language/:tag separately, define them together, with /:tag as an optional URI element.

match '/:language(/:tag)', :to => 'posts#search_result'

I believe routes are matched (and URIs generated from them) in the order that the routes are defined. You defined /:lang before you defined /:lang/:tag, so it matched /:lang and made :tag a GET parameter. I suppose you could optimize the ordering of your definitions, but I believe using the above syntax is the preferred method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文