过滤索引操作的路由和命名空间

时间:2013-04-15 18:52:51

标签: ruby-on-rails ruby-on-rails-3

我有一个事件模型和一个events_type模型。所有事件都从event_type模型中分配了一个id。

在我的事件索引操作/视图中,我有一个过滤器,允许我通过查找在url中传递的id来过滤和查看所选类型的事件。例如;的的http:本地主机:3000 /事件EVENT_TYPE = 2

我想要做的是使用event_type名称,而不是这样; http:localhost:3000 / events / film 等我还希望能够为每个event_type提供唯一的元标记(这可能意味着迁移到我的event_type模型中添加字段)。 / p>

任何人都可以提供一些如何批准这方面的帮助吗?它只是一个路由/名称空间的东西吗?

1 个答案:

答案 0 :(得分:1)

您必须偏离路线中的resources方法才能添加动态功能。没关系,我实际上更喜欢这样做,如下面的答案所述。

基本策略是重写resources自己做的事情,添加一个可以捕获:event_type的额外路由端点。在这种情况下,我们会在覆盖它的任何内容之前有效地插入:event_type路由。

# routes.rb

# We want the vanilla index route to come first, then deal with the rest.
# Notice it receives no params.
get 'events'           to: 'events#index'

# Using scope or namespace gives us urls nested under that string:
#  /events/:event_type
# Using scope instead of namespace prevents the router for looking under a corresponding ruby module
# AKA if this was `namespace 'event_type' do`, it would look for a
#   `Events::EventsController#index` instead of using our `EventsController#index`.
# All of the `as:` statements are to preserve access to the standard
#   path+url helpers you get out of the box with `resources`.
# All of the `constraints:` are to prevent urls from overriding each other.
#   I don't believe they're strictly necessary in this example, but
#   explicit is better than implicit in your routes.
scope 'events' do
  get ':event_type/:meta',  to: 'events#index',     as: :event_by_type_and_meta, constraints: { :event_type => /[a-zA-Z]*/, :meta => /[a-zA-Z]*/ }
  get ':event_type',  to: 'events#index',     as: :event_by_type, constraints: { :event_type => /[a-zA-Z]*/ }
  get ':id/edit',     to: 'events#edit',      as: :edit_event,   constraints: { :id => /\d/ }
  get 'new',          to: 'events#new',       as: :new_event

  delete ':id',       to: 'events#destroy',   as: :delete_event, constraints: { :id => /\d/ }
  put ':id',          to: 'events#update',    as: :update_event, constraints: { :id => /\d/ }
  get ':id',          to: 'events#show',      as: :event,        constraints: { :id => /\d/ }

  post '',            to: 'events#create',     as: :create_event
  get '',             to: 'events#index',     as: :events
end

完成此操作后,您只需检查:event_type中的EventController并进行相应过滤即可。如果使用:meta标记,只需进一步细化过滤器。

class EventsController < ApplicationController

  def index
    if params[:event_type]
      @event_type = EventType.find_by_name(params[:event_type])
      @events = Event.includes(:event_types).where(["id NOT IN (?)", @event_type.events_ids]).all
    else
      @event_type = nil
      @events = Event.filed_under(@event_type).all
    end
  end

如果您没有制作RESTful API,我认为您应该避免使用resources期。您的用户将遇到的应用的第一部分是您的网址结构。它确实是用户体验中最容易被忽视的方面。明确说明你所有的路线有助于你思考这段经历,并断言我在下面使用的更细粒度的控制。

如果您只使用resource,那么离开路线也很容易。明确您的网址有助于您了解安全漏洞。