我会使用 before 过滤器来检查所需项目是否属于当前用户:
class TasksController < ApplicationController
before_filter :find_project, only: :create
def create
@task = @project.tasks.build(params[:task])
if @task.save
flash[:success] = "Task saved."
redirect_to edit_task_path(@task)
else
render :new
end
end
private
def find_project
@project = current_user.projects.where( id: params[ :task ][ :project_id ] ).first
redirect_to( root_path, notice: 'No such project' ) unless @project
end
end
因此,如果给定的 project_id 与属于当前用户的项目不匹配,他将被重定向出去。
但是,一种更方便的方式是使用嵌套资源:
resources :projects
resources :tasks, shallow: true
end
你会有这样的路线:
GET /projects/1/tasks (index)
GET /projects/1/tasks/new (new)
POST /projects/1/tasks (create)
GET /tasks/1 (show)
GET /tasks/1/edit (edit)
PUT /tasks/1 (update)
DELETE /tasks/1 (destroy)
但这不会有太大差异,您仍然需要检索 Post :
class TasksController < ApplicationController
before_filter :find_project, only: [ :index, :new, :create ]
before_filter :find_task, only: [ :show, :edit, :update, :delete ]
# other actions
def create
@task = @project.tasks.build(params[:task])
if @task.save
flash[:success] = "Task saved."
redirect_to edit_task_path(@task)
else
render :new
end
end
private
def find_project
@project = current_user.projects.where( id: params[ :project_id ] ).first
redirect_to( root_path, notice: 'No such project' ) unless @project
end
def find_task
@task = current_user.tasks.where( id: params[ :id ] ).first
redirect_to( root_path, notice: 'No such task' ) unless @task
end
end