【问题标题】:Rails Routing -- Adding Custom RouteRails 路由——添加自定义路由
【发布时间】:2013-08-24 16:25:39
【问题描述】:

我几乎可以肯定以前有人问过这个问题,但我似乎无法找到正确的单词序列来找到它。

我有一个资源 Games,它包含所有正常的资源路径。创建、编辑等。

我在 GamesController 中创建了一个名为 json 的新操作,我希望能够在 mydomain.com/games/json 访问该操作,但路由不断选择“json”作为 ID 并将其路由到“show”而是采取行动。

大概这是因为默认路由:

match ':controller(/:action(/:id))'

我尝试了很多方法,但无论我做什么,它都会一直路由到“显示”。我一直在尝试使用this guide 来解决这个问题,但对于刚接触 Rails 的人来说,它需要大量的学习和应用。

我想说,对于任何控制器 /json 都会将您带到 json 操作(而不是使用 id 'json' 显示),但我愿意为每个控制器单独指定它。

非常感谢任何帮助。 (即使这只是将我指向已经回答的问题。)在所有情况下,我都将尝试创建的路由置于默认路由之上。

我的路线:

  root :to => 'home#index'
  resources :events, :players, :sets, :matches, :characters, :videos, :games, :event_instances, :game_instances
  resource :user_session
  resource :account, :controller => "users"
  resources :users
  match '/login', :to => 'user_sessions#new', :as => 'login'
  match '/logout', :to => 'user_sessions#destroy', :as => 'logout'
  match '/register', :to => 'users#create', :as => 'register'
  match '/games/json', :to => 'games#json', :as => 'gameList'
  match ':controller(/:action(/:id))'

【问题讨论】:

  • 你能显示你的路线吗?我们需要它来有效地回答。
  • 可能应该知道。它们已被添加。
  • 谢谢,我已经回答了你的问题,我认为

标签: ruby-on-rails rails-routing


【解决方案1】:

好的,你需要做的就是将你的自定义 json 路由放在你的其他资源路由之上,并将其设为默认值,如下所示:

get '/:controller/json(/:id)', action: 'json'
resources :events, :players, :sets, :matches, :characters, :videos, :games,         :event_instances, :game_instances
...

您的困惑与构建路由和解析 url 的方式有关

将您的 routes.rb 文件视为一组连续的过滤器,以应用于客户端请求的 url。

如果您将默认路由放在另一个上面,它将捕获与给定模式匹配的所有请求 => 这意味着当您在 json 路由上方添加所有资源路由时,所有与 /#{resources}/ 匹配的 url: id 模式(和 /games/json 就是其中之一)在到达 json 自定义路由之前被捕获。

通过将您的自定义路由置于其他路由之上,您可以让它捕获任何与该模式匹配的请求,这意味着在这种情况下所有带有

的请求
/#{controller_name or resource_name)}/json(/:id)

注意:

我不太确定这是用于您的路由的最佳设计模式,我宁愿使用带有基本 CRUD 操作的传统 REST 路由,这些操作将实现 response_to 模式来回答特定的 json 请求。

请参阅文档:http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to

当您的应用程序增长时,在您的所有资源之上添加这种“包罗万象”的路线可能会变得有风险。

但是你可能有你这样的理由,在那种情况下,我认为我的回答符合你的需要。

【讨论】:

    【解决方案2】:
    resources :games do
      collection do
        get :json
      end
    end
    

    如果您还想添加一个动作,该动作将采用 :id 路径段并返回,例如,特定游戏的 json 表示,您可以这样做

    resources :games do
      collection do
        get :json
      end
      member do
        get :json
      end
    end
    

    我要补充一点,当我刚接触 Rails 时(不到 1.5 年前),由于某种原因,路由 dsl 对我来说真的很难理解。但值得研究该指南,尽管它起初有点压倒性。否则你最终会得到一堆match '/route/to/somewhere' => 'controller#action', :as => :some_helper,这最终会让人难以阅读和维护,并且会让你的网址更难拥有一致的“语法”。

    编辑:查看您现在发布的路线文件,问题是您在resources :games 声明之后声明了games/json 路线。路由匹配优先级从文件顶部向下进行,因此games 的资源路由首先匹配,并且从不检查稍后声明的特定路由。如果您使用上述语法使您的 json 路由成为资源声明的一部分,则不会发生这种情况。

    【讨论】:

    • 正确。当您不确定自己在寻找什么时,很难找到答案。万分感谢。 (我链接的指南中的那部分现在更有意义了,因为它有一些上下文。)
    • 参见。 NicoArbogast 的回答。他的策略会为你的资源控制器定义一个json 路由,这可能是你想要的行为。 (我个人还是会使用get 而不是match。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 2021-10-07
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多