在路径(嵌套资源) - 导轨中找到上面的资源



我正在构建一个具有以下资源设置的应用程序:

User
  Team
    Invite
    Project
      Invite

users有一个teamteams有许多projects。可以邀请usersteams级别加入(并可以访问teams拥有的任何projects(或在project级别上邀请(仅让受邀者访问单个项目(。

我试图设置邀请以动态查找其父资源(即:TeamProject(。据我了解,最好的方法是看路径。目前的路径看起来像:

  • /teams/:id/invites/
  • /teams/:id/projects/:id/invites

是否可以从路径中的当前资源中查看一个"嵌套级别",以在控制器操作中查找父资源(例如:invites#new(?

谢谢!

澄清

我希望能够为teamsprojects资源使用相同的invites代码。当调用invites#new操作时,它将检查路径以查看资源所称的。如果路径为/teams/:id/invites/,它将返回team,然后我可以通过:id找到路径,如果路径为/teams/:id/projects/:id/invites,它将返回project,然后再次,我可以通过:id找到。

这是可能的吗?

首先不要筑巢一个以上的级别。

经验法则:资源绝不应该超过1级 深的。收藏可能需要由其父母范围 成员可以随时直接通过ID访问,不需要 范围(除非出于某种原因ID不是唯一的(。
-Jamis Buck

您的路径应该看起来像:

/teams/:team_id/invites
/projects/:project_id/invites

这提供了所需的所有上下文!添加更多的嵌套只会增加膨胀和过度复杂化,并使API差。

要为嵌套多态性资源创建可重复使用的控制器,您可以使用路由问题:

concerns :inviteable do
  resources :invites, shallow: true
end
resources :teams, concerns: :inviteable
resources :projects, concerns: :inviteable

您可以为邀请设置控制器,以检查存在哪个父param:

class InvitesController < ApplicationController
  before_action :set_parent, only: [:new, :create, :index]
  # GET /teams/:team_id/invites/new
  # GET /projects/:team_id/invites/new
  def new
    @invite = @parent.invites.new
  end
  # GET /teams/:team_id/invites
  # GET /projects/:team_id/invites
  def index
    @invites = @parent.invites
  end
  # POST /teams/:team_id/invites
  # POST /projects/:team_id/invites
  def create
    @invite = @parent.invites.new(invite_params)
    # ...
  end
  # ...
  private
  def parent_class
    if params[:team_id]
      Team
    elsif params[:project_id]
      Project
    end
  end
  def parent_param
    params[ parent_class.model_name.singular_route_key + "_id" ]
  end
  def set_parent
    @parent = parent_class.find(parent_param)
  end 
end 

路由是:

/teams/:team_id/invites/new //note that it should be team_id, not :id,

/teams/:team_id/projects/:project_id/invites/new

您可以始终通过这些参数检查嵌套。如果

params [:project_id] .present?

然后您不在/teams/:team_id/projects/:project_id/邀请路线,邀请_type应该是项目。否则,它应该是/teams/:team_id/invites/,并且邀请_type应该是团队。

最新更新