轨道=>根据 current_user 将索引路由到两个不同的页面
我正在使用 Rails,并且在预订时有两种视图(客户和培训师)。我正在尝试根据当前用户是谁从索引路由到客户或培训师。
如果我是客户,请将索引发送给培训师 如果我是培训师,请将索引路由给客户
class BookingsController < ApplicationController
def index
end
def clients
@bookings = Booking.where(client: current_user)
@clients = current_user.bookings.map(&:client)
end
def trainers
@trainers = current_user.bookings.map(&:user)
end
end
Rails.application.routes.draw do
resources :bookings do
collection do
get "/clients", to: "bookings#clients", as: "clients"
get "/trainers", to: "bookings#trainers", as: "trainers"
end
resources :shared_training_plans, except: [:new]
end
end
I'm using Rails and I have two views in bookings (clients and trainers). I'm trying to route from index to client or trainers depending on who is the current_user.
If I'm a client, route index to trainers
If I'm a trainer, route index to clients
class BookingsController < ApplicationController
def index
end
def clients
@bookings = Booking.where(client: current_user)
@clients = current_user.bookings.map(&:client)
end
def trainers
@trainers = current_user.bookings.map(&:user)
end
end
Rails.application.routes.draw do
resources :bookings do
collection do
get "/clients", to: "bookings#clients", as: "clients"
get "/trainers", to: "bookings#trainers", as: "trainers"
end
resources :shared_training_plans, except: [:new]
end
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你正在向后嵌套。路由的输出实际上应该看起来更像:
这以 REST方式描述了端点返回属于其他资源的内容。这应该由
index
操作来处理 - 最好是为此目的指定一个控制器,因为每个控制器应该只负责一个资源。您可以将这些路由定义为:
您可以通过重新构想该功能来实现此目的,以便链接“特定用户 URL”而不是通用 URL。例如,您可以在 Stackoverflow 的仪表板上看到这一点,该仪表板使用
https://stackoverflow.com/users/{id}/{username}
。REST 理论上应该是无状态的,因此无论是谁请求,每个路径都应该返回相同的资源。但与所有规则一样,这可能会被破坏,您可以设置如下路由:
这将为有状态的登录用户返回不同的结果。这里的
user
将被视为单一资源。如果您在查看“您自己的”与“其他人”时需要有明显不同的资源表示,那么这非常有用。为了真正能够从路由中使用“当前用户”,身份验证系统必须作为 Rack 中间件(如 Devise )实现,而不是像几乎所有“重新发明轮子”教程那样在控制器级别实现。 Routing is Rails 被实现为机架中间件,在实例化控制器之前运行。
Devise 具有经过身份验证的路由帮助程序,可让您为经过身份验证/未经身份验证的用户设置不同的路由。例如,如果讲师被实现为不同的 Warden 范围:
但如果您只有一个 Warden 范围(典型的 Devise 配置),您也可以使用 lambda:
这两种方式都会将
GET /bookings
路由到Instructors::BookingsController#index
和Students::BookingsController#index
取决于用户拥有的“角色”。You're doing nesting backwards. And the output of your routes should actually look more like:
This describes RESTfully that the endpoint returns something belonging to the other resource. This should be handled by the
index
action - ideally of a controller designated for that purpose as each controller should only be responsible for one resource.You could define these routes as:
You can implement this by reimagining the feature so that you link the "specific users URL" instead of a generic URL. You can see this for example on the dashboard here on Stackoverflow which uses
https://stackoverflow.com/users/{id}/{username}
.REST is in theory supposed to be stateless so each path should return the same resource no matter who is requesting it. But like all rules this could be broken and you can set up routes like:
Which would return different results for the signed in user which is stateful.
user
here would be consider a singular resource. This is mostly useful if you need to have a significantly different represention of the resource when viewing "your own" vs "others".To actually be able to use the "current user" from the routes the authentication system must be implemented as Rack middleware (like Devise is) and not on the controller level as almost all the "reinventing the wheel" tutorials are. Routing is Rails is implemented as Rack middeware that is run before your controller is ever instanciated.
Devise has the
authenticated
routing helper which lets you setup different routes for authenticated/unauthenticated users. For example if instructors are implemented as different warden scopes:But you could also use a lambda if you only have one warden scope (the typical Devise configuration):
Both of these would route
GET /bookings
toInstructors::BookingsController#index
andStudents::BookingsController#index
depending on which "role" the user has.