【问题标题】:Rails: How to parameterize access to a RESTful resource?Rails:如何参数化对 RESTful 资源的访问?
【发布时间】:2010-02-02 15:04:09
【问题描述】:

我正在寻找一种将选项传递给服务的宁静方式。现在我有一个以标准 rails 方式访问的设备资源:

map.resources :devices, :member => [:historical]

所以我可以使用/devices/:id 获取我的设备,我可以使用/devices/:id/historical 获取历史数据

我想在指定范围的历史 URL 上实际添加一个参数,因此当我查询历史数据时,我可以按小时、每天、每周、每月取回它。类似/devices/:id/historical/:range

有没有办法修改我上面的路线设置以适应这种情况?还是我只需要像 /devices/:id/historical?range=hourly 一样传递它

我更喜欢前者,但我不确定这是否违反了 Restful 约定或者最好的解决方法是什么。

【问题讨论】:

    标签: ruby-on-rails rest routing


    【解决方案1】:

    我认为您的问题实际上归结为如何知道何时适合将某物表示为资源以及何时使用查询字符串对其进行参数化。

    我不知道您的域,但从您的问题来看,有关设备的历史数据似乎是一种资源,并且通过范围访问该数据的子集最好表示为查询字符串,就像您可能会对大量项目列表进行分页。

    另外需要考虑的是缓存,因为如果你想单独对每个范围进行页面缓存,那么你将不得不在路由中使用路径段,即:range。这样,Rails 将在磁盘上生成一个唯一的 HTML 文件来表示该范围。如果您使用查询字符串,那么它将被有效地忽略,并且将为不同的范围返回相同的 HTML 文件。

    【讨论】:

    • 那么出于兴趣,您知道我如何将 :range 添加到我的历史 URL 中,而无需编写单独的命名路由。是否可以选择将参数添加到 Rails 中的路线?我还没找到
    • @brad 你可以为 url 助手传递参数 link_tohistory_reports_path(device, :range => 'daily')
    • 是的,我知道,我更感兴趣的是调整路由本身,使其不是查询字符串,而是资源标识符,而不是 /devices/:id/historical?range =每天但 /devices/:id/historical/:range
    • 我不明白你的问题。做你有的事:/devices/:id/historical/:range
    • 好的,现在使用 map.resources :devices, :member => [:historical] 我有 url: /devices/:id/historical 所以我不知道如何修改该路线定义知道'historical'之后的参数被称为:range
    【解决方案2】:

    将范围作为路径段或查询参数都可能是 RESTful。

    这个问题实际上是一个设计问题。您想将历史数据建模为带有参数的单个资源,还是想建模多个资源?这与我们在进行 OO 设计时做出的决定相同。你想要一个具有类型属性的类还是一堆子类?或者数据库设计,我们是把数据存储在多张表中还是一张表里有一个discriminator 列?

    只要您正确使用 HTTP 动词来操作该资源,那么您就不会违反相关的 REST 约束。

    【讨论】:

      【解决方案3】:

      在我看来是这样的:

      match 'devices/:id/historical/:range' => 'devices#historical_filter'
      

      可能会有所帮助,尽管它需要您在控制器中做的工作比您希望的要多(:id 和 :range 都成为参数)。它会强制您使用命名路由而不是资源丰富的路由路径,但如果您对此而不是查询参数设置了心,那么它可能值得一看。

      【讨论】:

        猜你喜欢
        • 2011-10-14
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-17
        • 2014-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多