2013-04-15 42 views
1

我有一个事件模型和一个events_type模型。所有事件都从event_type模型中分配一个id。已过滤索引操作的路由和名称空间

在我的事件索引动作/视图我有一个过滤器,允许我通过查找在URL中传递的ID过滤和查看所选类型的事件。例如; http:localhost:3000/events?event_type = 2

我想要做的就是用event_type这个名字来替代这个名字; http:localhost:3000/events/film等等,我也希望能够为每个event_type提供独特的元标记(这可能意味着将字段添加到我的event_type模型中)。

任何人都可以提供一些关于如何批准这方面的帮助吗?它只是一个路由/命名空间的事情?

回答

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_typeEventController,并相应地进行筛选。如果使用: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,那么也很容易留下真正不应该暴露的路线。明确您的URL有助于您了解安全漏洞。

+0

这看起来很棒,今天我会试试看。感谢这样深入的回答! – Raoot

+0

这真的很好,谢谢,但我遇到了一个我最初并未考虑的问题;我如何处理我的事件显示,如果我要移动到使用slu instead而不是ID?目前,通过上面的路由,事件/乐队生活将被视为event_type。 – Raoot

+0

这会让事情变得复杂。关于我的头顶,最简单的方法是将事件的event_types url命名为'events/type /:event_type'。 –