对Rails中的嵌套资源和身份验证感到困惑

时间:2012-12-30 12:58:33

标签: ruby-on-rails devise associations crud

让我们看看我是否能够很好地解释自己的疑虑。

我有一个由Devise管理的用户模型。所以在我的路线中我有:

devise_for :users

用户模型中,我与模型计划有关联。关联是:

User has_many Plans
Plan belongs_to User

此时我还有计划模型的资源,因此我可以获取所有计划,显示特定计划等。但我想更进一步。

我希望能够看到特定用户的计划,并让特定用户查看自己的计划并进行编辑。

所以,例如,每当我去:

/用户/:ID /计划

我希望能够看到该特定的计划:id用户。如果访问该URL的用户是登录的用户,我希望他能够编辑这些计划。

如何管理所有这些行为?有没有任何宝石可以帮助它?或者我需要在视图中做条件,如果是current_user ...

2 个答案:

答案 0 :(得分:4)

让我们从路线开始,您可以像这样制作路线:

resources :users do
  resources :plans, only: [:index]
end

resources :plans, except: [:index]

我在resources :plans中使用resources :users来获得此/users/:user_id/plans之类的路线,而resources :plans外部用于其他操作(编辑,销毁,...... )不需要user_id,即计划由唯一ID标识,因此您不需要user_id从数据库中获取它以进行编辑或销毁。

现在对于控制器,我们可以这样做:

class PlansController < ApplicationController
  before_filter :is_plan_owner?, only: [:edit, :update]

  def index
    @plans = Plan.where(:user_id => params[:user_id])
  end

  def edit
    @plan = Plan.find(params[:id])
  end

  private

  def is_plan_owner?
    if current_user != Plan.find(params[:id]).user
      # Scream, shout, call 911 and/or redirect else where
    end
  end
end

答案 1 :(得分:4)

这与使用任何其他嵌套资源没什么不同。 devise_for文件中对routes.rb的调用不会向用户模型提供RESTful路由。只需标准的Devise安装,就可以在没有嵌套资源的情况下考虑一下。如果你去rake routes,你会得到类似于以下内容的东西:

  new_user_session GET  /users/sign_in(.:format)       devise/sessions#new
      user_session POST /users/sign_in(.:format)       devise/sessions#create
     user_password POST /users/password(.:format)      devise/passwords#create
 new_user_password GET  /users/password/new(.:format)  devise/passwords#new
edit_user_password GET  /users/password/edit(.:format) devise/passwords#edit
           sign_in GET  /sign_in(.:format)             devise/sessions#new

这不会为索引或显示用户提供任何内容,因此您仍需要为其添加路由:

resources :users, only: [:index, :show]

现在你得到:

users GET /users(.:format)     users#index
 user GET /users/:id(.:format) users#show

好的,现在我们已经到了某个地方,然后它只是添加了嵌套资源,而Devise毫不介意。

resources :users, only: [:index, :show] do
  resources :plans
end

这为您提供了您想要的资源路由

    user_plans GET /users/:user_id/plans(.:format)          plans#index
              POST /users/:user_id/plans(.:format)          plans#create
 new_user_plan GET /users/:user_id/plans/new(.:format)      plans#new
edit_user_plan GET /users/:user_id/plans/:id/edit(.:format) plans#edit
     user_plan GET /users/:user_id/plans/:id(.:format)      plans#show
               PUT /users/:user_id/plans/:id(.:format)      plans#update
            DELETE /users/:user_id/plans/:id(.:format)      plans#destroy

这就是它的全部内容。设计会在这个问题上不受影响。