如何将命名参数解析为Sinatra中的路径?

时间:2016-01-03 16:04:52

标签: html sinatra

我正在创建一个书签管理器应用程序,它提供了一个链接列表。每个链接都有一个或多个标记。我想让网站用户能够按标签过滤链接。用户应该能够键入标签的名称,然后单击标记为'按标签过滤的按钮'。这应该仅提供具有该标记的链接的列表。

因此,我的html表格如下:

<form action='/tags/:name’ method='get'>
  <label for='name'>
    Tag:
    <input type='text' name='name'>
  </label>
  <input type='submit' value='Filter by tag'>
</form>

我的控制器如下:

class BookmarkManager < Sinatra::Base
  get '/tags/:name’ do
    tag = Tag.first(name: params[:name])
    @links = tag ? tag.links : []
    erb :'links/index'
  end
end

我运行了机架,并尝试使用标签过滤我的链接。当我输入并提交标签名称时,提交的名称是':name'而不是键入的文本。因此,不显示与特定标记相关的链接,而是显示没有链接。

2 个答案:

答案 0 :(得分:0)

我建议您将name作为queryString参数传递,而不是使用magic route /:name。如果您将HTML更改为此应用程序应该可以正常工作:

<form action='/tags' method='get'>
  <label for='name'>
    Tag:
    <input type='text' name='name'>
  </label>
  <input type='submit' value='Filter by tag'>
</form>

将sinatra路线改为:

class BookmarkManager < Sinatra::Base
  get '/tags’ do
    raise ArgumentError, "Name is required in order to show a tag" unless params[:name]
    tag = Tag.first(name: params[:name])
    @links = tag ? tag.links : []
    erb :'links/index'
  end
end

此外,如果未将name传递给路由,则路由现在会引发异常。这是验证输入的好方法。

答案 1 :(得分:0)

管理如下解决问题:

在html中:

<form action='/tags' method='get'>
  <label for='name'>
    Tag:
    <input type='text' name='name'>
  </label>
  <input type='submit' value='Filter by tag'>
</form>

在控制器中:

class BookmarkManager < Sinatra::Base
  get '/tags' do
    redirect "/tags/#{params[:name]}"
  end
  get '/tags/:name' do
    tag = Tag.first(name: params[:name])
    @links = tag ? tag.links : []
    erb :'links/index'
  end
end

所以现在当我按标签过滤时,我的网址会显示标记名称。