您必须与路线中的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
,那么也很容易留下真正不应该暴露的路线。明确您的URL有助于您了解安全漏洞。
这看起来很棒,今天我会试试看。感谢这样深入的回答! – Raoot
这真的很好,谢谢,但我遇到了一个我最初并未考虑的问题;我如何处理我的事件显示,如果我要移动到使用slu instead而不是ID?目前,通过上面的路由,事件/乐队生活将被视为event_type。 – Raoot
这会让事情变得复杂。关于我的头顶,最简单的方法是将事件的event_types url命名为'events/type /:event_type'。 –