Ruby on rails 如何正确设置为用户分配角色的路由

Ruby on rails 如何正确设置为用户分配角色的路由,ruby-on-rails,routing,routes,Ruby On Rails,Routing,Routes,假设我有一个“成员””和一个“项目””模型 “成员”和“模型”反映了多对多关联,并通过项目成员联接表进行链接 任何成员都可以在与其关联的所有项目中扮演不同的角色 我正在尝试编写一个“添加角色”和“删除角色”方法来为成员分配角色 因为角色应该按项目/成员分配,所以我构建了一个控制器“project\u members\u controller”,在这里我可以编写这些方法 但我感到困惑的是,考虑到我为这些方法定义路由的方式,我得到了两条具有相同路径的POST路由。因此,听起来好像我做错了什么,或者不

假设我有一个“成员””和一个“项目””模型

成员”和“模型”反映了多对多关联,并通过项目成员联接表进行链接

任何成员都可以在与其关联的所有项目中扮演不同的角色

我正在尝试编写一个“添加角色”和“删除角色”方法来为成员分配角色

因为角色应该按项目/成员分配,所以我构建了一个控制器“project\u members\u controller”,在这里我可以编写这些方法

但我感到困惑的是,考虑到我为这些方法定义路由的方式,我得到了两条具有相同路径的POST路由。因此,听起来好像我做错了什么,或者不理解Rails是如何工作的

目前我的路线定义为:

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
    post "collaborators/:id/set_role", to: "project_members#set_role"
    post "collaborators/:id/remove_role", to: "project_members#remove_role"
  end
end
               Prefix Verb   URI Pattern                                           Controller#Action
collaborators_project GET    /projects/:id/collaborators(.:format)                 members/members#index
                      POST   /projects/:id/collaborators/:id/set_role(.:format)    project_members#set_role
                      POST   /projects/:id/collaborators/:id/remove_role(.:format) project_members#remove_role
             projects GET    /projects(.:format)                                   projects#index
                      POST   /projects(.:format)                                   projects#create
          new_project GET    /projects/new(.:format)                               projects#new
         edit_project GET    /projects/:id/edit(.:format)                          projects#edit
              project GET    /projects/:id(.:format)                               projects#show
                      PATCH  /projects/:id(.:format)                               projects#update
                      PUT    /projects/:id(.:format)                               projects#update
                      DELETE /projects/:id(.:format)                               projects#destroy
def set_role
  @project = params[:project_id]
  if @project.owner.id == current_member.id
    @project_member = ProjectMember.where(project_id: @project.id, member_id: params[:id])
    @project_member.add_role(:observer) if self.roles.blank?
    # CODE RENDERING OUTPUT
    render html: "<h1>HOLA</h1>"
  else
    # CODE THROWIGN AN ERROR
  end
end
按以下路线翻译:

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
    post "collaborators/:id/set_role", to: "project_members#set_role"
    post "collaborators/:id/remove_role", to: "project_members#remove_role"
  end
end
               Prefix Verb   URI Pattern                                           Controller#Action
collaborators_project GET    /projects/:id/collaborators(.:format)                 members/members#index
                      POST   /projects/:id/collaborators/:id/set_role(.:format)    project_members#set_role
                      POST   /projects/:id/collaborators/:id/remove_role(.:format) project_members#remove_role
             projects GET    /projects(.:format)                                   projects#index
                      POST   /projects(.:format)                                   projects#create
          new_project GET    /projects/new(.:format)                               projects#new
         edit_project GET    /projects/:id/edit(.:format)                          projects#edit
              project GET    /projects/:id(.:format)                               projects#show
                      PATCH  /projects/:id(.:format)                               projects#update
                      PUT    /projects/:id(.:format)                               projects#update
                      DELETE /projects/:id(.:format)                               projects#destroy
def set_role
  @project = params[:project_id]
  if @project.owner.id == current_member.id
    @project_member = ProjectMember.where(project_id: @project.id, member_id: params[:id])
    @project_member.add_role(:observer) if self.roles.blank?
    # CODE RENDERING OUTPUT
    render html: "<h1>HOLA</h1>"
  else
    # CODE THROWIGN AN ERROR
  end
end
URI模式是我的目标,但这听起来像是一个好的实践吗

如果添加角色和删除角色方法共享同一路径,如何访问带有链接的添加角色和删除角色方法。我应该在帮助器中创建一个url块吗?而且

这样做时使用POST是正确的还是应该使用补丁

谢谢你的指导

作为参考,我的“project\u members\u controller.rb”包含如下内容:

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
    post "collaborators/:id/set_role", to: "project_members#set_role"
    post "collaborators/:id/remove_role", to: "project_members#remove_role"
  end
end
               Prefix Verb   URI Pattern                                           Controller#Action
collaborators_project GET    /projects/:id/collaborators(.:format)                 members/members#index
                      POST   /projects/:id/collaborators/:id/set_role(.:format)    project_members#set_role
                      POST   /projects/:id/collaborators/:id/remove_role(.:format) project_members#remove_role
             projects GET    /projects(.:format)                                   projects#index
                      POST   /projects(.:format)                                   projects#create
          new_project GET    /projects/new(.:format)                               projects#new
         edit_project GET    /projects/:id/edit(.:format)                          projects#edit
              project GET    /projects/:id(.:format)                               projects#show
                      PATCH  /projects/:id(.:format)                               projects#update
                      PUT    /projects/:id(.:format)                               projects#update
                      DELETE /projects/:id(.:format)                               projects#destroy
def set_role
  @project = params[:project_id]
  if @project.owner.id == current_member.id
    @project_member = ProjectMember.where(project_id: @project.id, member_id: params[:id])
    @project_member.add_role(:observer) if self.roles.blank?
    # CODE RENDERING OUTPUT
    render html: "<h1>HOLA</h1>"
  else
    # CODE THROWIGN AN ERROR
  end
end
def set_角色
@project=params[:project\u id]
如果@project.owner.id==current_member.id
@project_member=ProjectMember.where(project_id:@project.id,member_id:params[:id])
@项目\成员。如果self.roles.blank,是否添加\角色(:观察员)?
#代码呈现输出
呈现html:“HOLA”
其他的
#代码错误
结束
结束

您可以编写一个用于添加/删除角色的通用方法
manage_roles
,而不是使用单独的方法来添加和删除角色

修改路由文件。

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
    post "collaborators/:id/manage_roles", to: "project_members#manage_roles"
  end
end
您可以通过单击链接来传递参数,在此基础上可以标识添加或删除角色

<%= link_to "Add Role", <manage_roles path> , {role_action: 'add_role', method: :post} %>

您可以编写一个用于添加/删除角色的通用方法
manage\u roles
,而不是使用单独的方法来添加和删除角色

修改路由文件。

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
    post "collaborators/:id/manage_roles", to: "project_members#manage_roles"
  end
end
您可以通过单击链接来传递参数,在此基础上可以标识添加或删除角色

<%= link_to "Add Role", <manage_roles path> , {role_action: 'add_role', method: :post} %>

始终使用RESTfulRails路径

您可以将路线更改为以下路线

更新1:

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
  end
  resources :collaborators, only: [:create, :destroy]
end
更新2:

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
  end
  resources :collaborators, only: [] do
    member do
      post 'set_role', => 'project_members#set_role'
      post 'remove_role' => "project_members#remove_role"
    end
  end
end
更新3:

resources :projects do
  resources :collaborators, only: [] do
    get '/' => "members/members#index", on: :collection
    member do
      post 'set_role' => 'project_members#set_role'
      post 'remove_role' => "project_members#remove_role"
    end
  end
end

始终使用RESTfulRails路径

您可以将路线更改为以下路线

更新1:

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
  end
  resources :collaborators, only: [:create, :destroy]
end
更新2:

resources :projects do
  member do
    get "collaborators", to: "members/members#index"
  end
  resources :collaborators, only: [] do
    member do
      post 'set_role', => 'project_members#set_role'
      post 'remove_role' => "project_members#remove_role"
    end
  end
end
更新3:

resources :projects do
  resources :collaborators, only: [] do
    get '/' => "members/members#index", on: :collection
    member do
      post 'set_role' => 'project_members#set_role'
      post 'remove_role' => "project_members#remove_role"
    end
  end
end

普拉莫德,谢谢你的回答。我可能确实使用了一种方法,但关于复制路径的问题仍然存在。在您的示例manage_roles方法中,我想向该控制器发出的任何POST请求都将与共享同一路径。@Andrew,在为成员创建角色时使用POST是正确的。Pramod,谢谢您的回答。我可能确实使用了一种方法,但关于复制路径的问题仍然存在。在您的示例manage_roles方法中,我想向该控制器发出的任何POST请求都将与共享同一路径。@Andrew,在为成员创建角色时在此处使用POST是正确的。我知道,但如果控制器不可用,会发生什么情况。在这种情况下,Rolify控制器是隐藏的。在这种情况下,RESTful路由是不够的,因为我在另一个控制器中,对吗?你在哪个控制器中?根据我上面的问题,我在项目_members _controller.rb中添加这些方法,只是因为没有“roles _controller.rb”,因为所有角色都由Rolify Gem管理。我在想也许我应该创建一个角色控制器,并按照您的建议在那里使用RESTFul。不过,我担心这会破坏gem。谢谢Ashvin,您的解决方案确实为路线添加了一条路径。但是,我得到了以下URI
/projects/:id/collaborators/:id/set_role(:format)
,我希望得到类似于
/projects/:community_id/collaborators/:id/set_role(:format)
的东西,其中第一个参数是:community_id和params[:id]对应协作者id。是否有任何方法可以实现URI应该是从更新2开始的
/projects/:project\u id/collaborators/:id/set\u role(:format)
,但在控制器不可用的情况下会发生什么。在这种情况下,Rolify控制器是隐藏的。在这种情况下,RESTful路由是不够的,因为我在另一个控制器中,对吗?你在哪个控制器中?根据我上面的问题,我在项目_members _controller.rb中添加这些方法,只是因为没有“roles _controller.rb”,因为所有角色都由Rolify Gem管理。我在想也许我应该创建一个角色控制器,并按照您的建议在那里使用RESTFul。不过,我担心这会破坏gem。谢谢Ashvin,您的解决方案确实为路线添加了一条路径。但是,我得到了以下URI
/projects/:id/collaborators/:id/set_role(:format)
,我希望得到类似于
/projects/:community_id/collaborators/:id/set_role(:format)
的东西,其中第一个参数是:community_id和params[:id]对应协作者id。是否有任何方法可以实现从更新2开始URI应为
/projects/:project\u id/collaborators/:id/set\u role(:format)