您必须从路由中的 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
有了这些,您只需在您的EventController 中检查:event_type 并进行相应的过滤。如果使用: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 句点。您的用户将遇到的应用程序的第一部分是您的 URL 结构。这确实是用户体验中最被忽视的方面。明确说明您的所有路线有助于您通过这种体验进行思考,并断言我在下面使用的更细粒度的控制。
如果您只使用resource,也很容易留下不应该暴露的路线。明确使用 URL 有助于您了解安全漏洞。