1

我已经为“发票”设置了一个标准的资源丰富的路由设置,但是我希望添加基于状态过滤发票记录的功能。

/invoices - shows all invoices
/invoices/unpaid - shows all unpaid invoices
/invoices/paid - shows all paid invoices.
/invoices/3 - shows invoice #3

我已经用明确定义的匹配路线让这个工作没有问题。

match "/invoices/pending" => "invoices#index", :state => 'pending'

然而,随着可能的状态越来越多,这意味着定期修改路线,也意味着我经常重复自己。

我的下一个尝试是使用匹配路由中的命名参数使这条路由更具动态性。

match "/invoices/:state" => "invoices#index"

但是,这会否定 /invoices/id 路由并尝试查找 /invoices/3 找不到任何记录,因为它正在根据 state 参数进行搜索。

任何人都可以帮助定义一个可以动态工作的过滤器路由吗?

4

3 回答 3

1

在路由中添加正则表达式作为约束:

match "/invoices/:id" => "invoices#show", :id => /\d+/
match "/invoices/:state" => "invoices#index"

它应该选择唯一编号的 id-s 用于显示,其余的用于索引。

于 2013-05-13T13:36:20.253 回答
0

尝试使用路由约束。就像是

match "/invoices/:id" => "invoices#show", constraint: { id: /\d+/ }
match "/invoices/:state" => "invoices#index", constraint: { state: /\w+/ }
于 2013-05-13T13:36:27.580 回答
0

我决定采取稍微不同的路线(请原谅双关语),通过添加一个约束,而不是使用 REGEX 使用一种方法直接在状态机上查看可能的状态。

# State based routes, which match the state machine dynamicly.
match "/invoices/:state" => "invoices#index", constraints: lambda { |r|
    # Get an array if potential state names.
    states = Invoice.state_machine.states.map &:name

    # See if the request state name matches or not.
    states.include?(r.params[:state].parameterize.underscore.to_sym)
}

# Resource routes go here.

这基本上意味着如果我现在去寻找 /invoices/paid 或 /invoices/unpaid 我会得到我预期的索引操作,状态变量设置为 expeetd。

但是,执行 /invoices/pay_soon 之类的不是有效事件的操作会返回 404。

对该解决方案非常满意,但感谢其他建议让我走上了使用约束的轨道。

于 2013-05-13T15:48:36.033 回答