尝试通过嵌套路由过滤数据

时间:2013-04-19 04:39:55

标签: ruby-on-rails

我有一个Rails应用程序,可以让用户提出问题,由专业人士回答。除问答模型外,应用程序还以下列方式跟踪类别

Question.rb

 has_many :categorizations
 has_many :categories, through: :categorizations

Category.rb

  has_many :categorizations
  has_many :questions, through: :categorizations

Categorization.rb

 belongs_to :question
 belongs_to :category

现在,我可以访问localhost:3000 / categories并查看其中包含问题的所有类别的列表。然而,尽管类别很重要,但它并不实用,因为由于问题的性质,加利福尼亚州的人不太可能回答有关纽约的问题。因此,我也希望按位置过滤问题。我猜测设置URL的最佳方式就是这样

localhost:3000/state/ny/categories

我理解我可以通过创建嵌套路由来做(例如,如果我创建了一个位置资源)

resources :states do
    resources :categories 
end 

所以,尽管我最初将该位置存储为Question模型中的一个字段,但我现在创建了一个Location模型(如果'State'是一个保留字,我不确定)。我做了

Location.rb

has_many :questions

Question.rb

belongs_to :locations

并且还进行了嵌套路由,因此我可以按状态过滤类别

  resources :locations do
        resources :categories 
  end 

但是,你会注意到我没有在位置和类别之间建立关联,所以如果我去这条路线

http://localhost:3000/locations/ny/categories

如果index.html.erb视图页面显示每个类别存在多少问题

<% @categories.each do |category| %>
  <div class="category">
    <h5><%= link_to category.name, category %></h5>
    <%= pluralize category.questions.size, "question" %>
  </div>
<% end %>

它没有按位置过滤。例如,无论位置如何,它仍会计算所有问题。除非我在视图中添加一些过滤位置的逻辑,否则拥有这样的路径没有任何好处。

除了类别,我还尝试了嵌套问题,但这显然不会改变任何东西。

  resources :locations do
        resources :questions
  end 

我想你可以看到我正在尝试做什么。你能建议我该怎么做。

例如,我是否应该在位置和类别之间创建关联,如果是这样,它如何使用我有分类的连接模型 - 它是否属于其他三个模型。或者我应该如何过滤按位置列出的类别中的问题或问题。

谢谢你能提供一些指示。

2 个答案:

答案 0 :(得分:1)

当您有独特的要求时,我认为您不应该使用嵌套资源进行路由。我会像这样设置路由

get locations/:state/categories => "categories#index"
get locations/categories => "categories#index"

categories#index内部,我会根据此检查if params[:state].nil?您可以决定是否按检索查询中的状态进行过滤,并且视图将保持不变

答案 1 :(得分:1)

在嵌套路由到位的情况下,过滤不会自动发生,您仍然需要手动完成。嵌套路线可以使事情变得更容易管理,也可以增强用户的体验,而不是为您做繁重的工作。因此,在您的情况下,在您的视图中,您需要更改用于获取计数的代码,如下所示:

category.questions.where(location_id: params[:location_id]).size

您正在使用通过网址传入的:location_id来过滤它。这里还有其他一些问题:首先,这种逻辑应该不在视图中,但可能在你的模型中;更严重的是,默认情况下,rails需要使用网址中的位置:id,而不是名称/缩写,因此您需要路由为/location/1/categories而不是/locations/ny/categories(尽管有是可以让你绕过这个要求的宝石。)