2013-04-15 30 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'。 –

相關問題