2016-09-26 61 views
0

我想为用户项目的“取消”方法,而不是删除记录,它将状态更新为“取消”,存储取消前的最后状态并记录用户的原因(输入)。自定义方法不工作的Rails嵌套资源?

我有用户(设计)和嵌套项目的控制器。 REST风格的动作似乎一切正常,但取消选项并没有,我不知道!

这里是我的routes.rb

devise_for :users 

resources :users do 
    resources :projects do 
    get "cancel" => 'projects#cancel' 
    post "cancel" => 'projects#cancel_save' 
    end 
end 

当我运行rake routes

   user_project_cancel GET /users/:user_id/projects/:project_id/cancel(.:format) projects#cancel 
           POST /users/:user_id/projects/:project_id/cancel(.:format) projects#cancel_save 
        user_projects GET /users/:user_id/projects(.:format)     projects#index 
           POST /users/:user_id/projects(.:format)     projects#create 
       new_user_project GET /users/:user_id/projects/new(.:format)    projects#new 
       edit_user_project GET /users/:user_id/projects/:id/edit(.:format)   projects#edit 
        user_project GET /users/:user_id/projects/:id(.:format)    projects#show 
           PATCH /users/:user_id/projects/:id(.:format)    projects#update 
           PUT /users/:user_id/projects/:id(.:format)    projects#update 
           DELETE /users/:user_id/projects/:id(.:format)    projects#destroy 

projects_controller.rb(我包括万一整个事情)

class ProjectsController < ApplicationController 
before_filter :deny_to_visitors 
before_action :correct_user, only: [:show, :edit, :update, :destroy, :cancel, :cancel_save] 
before_action :set_current_status, only: [:cancel, :cancel_save] 

def index 
    @projects = Project.all.order(id: :asc) 
end 

def show 
end 

def new 
    @project = current_user.projects.new 
    @budgets = Budget.all 
end 

def edit 
end 

def create 
    @project = current_user.projects.new(project_params) 
    @project.project_status_id = 1 
    if @project.save 
    redirect_to root_path, notice: 'Your project is being reviewed. We will be in contact soon!' 
    AdminMailer.new_project_email(current_user, @project).deliver_now 
    else 
    render :new 
    end 
end 

def update 
    if @project.update(project_params) 
    if admin_signed_in? 
     redirect_to admin_projects_list_path, notice: 'Project was successfully updated.' 
    else 
     redirect_to root_path, notice: 'Project was successfully updated.' 
    end 
    else 
    render :edit 
    end 
end 

def destroy 
    @project.destroy 
    redirect_to projects_url, notice: 'Project was successfully destroyed.' 
end 

def cancel 
end 

def cancel_save 
    @project.cancel_reason.update(:project_id, :last_status_id, :comment) 
    @project.update_attribute(:project_status_id, 10) 

    redirect_to root_path, notice: 'Project has been successfully cancelled.' 
end 

private 
    # Use callbacks to share common setup or constraints between actions. 
    def deny_to_visitors 
    redirect_to root_path unless user_signed_in? or admin_signed_in? 
    end 

def correct_user 
    if admin_signed_in? 
    @project = Project.find_by(id: params[:id]) 
    else 
    @project = current_user.projects.find_by(id: params[:id]) 
    end 
    redirect_to user_projects_path, notice: "You are not authorised to view this project" if @project.nil? 
    end 

def set_current_status 
    @current_status = current_user.projects.find_by(id: params[:id]).project_status_id 
end 

def project_params 
    params.require(:project).permit(:user_id, :project_type_id, :name, :industry_id, :description, :budget_id, :project_status_id, feature_ids:[], addon_ids:[]) 
end 

end 

链接在我看来

<%= link_to 'Edit', edit_user_project_path(current_user, project) %> 
<%= link_to 'Cancel', user_project_cancel_path(current_user, project) %> 

对于cancel.html.erb,我有一个超级简单的页面,目前甚至没有形式,直到我找出错误。

<h1>Cancel</h1> 
<p><%= @project.name %></p> 

修订

当我点击取消一个项目,我得到这个在轨服务器控制台日志:

Started GET "https://stackoverflow.com/users/1/projects/3/cancel" for ::1 at 2016-09-26 17:21:50 +0200 
    Processing by ProjectsController#cancel as HTML 
    Parameters: {"user_id"=>"1", "project_id"=>"3"} 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]] 
    Project Load (0.3ms) SELECT "projects".* FROM "projects" WHERE "projects"."user_id" = $1 AND "projects"."id" IS NULL LIMIT $2 [["user_id", 1], ["LIMIT", 1]] 
    Redirected to http://localhost:3000/users/1/projects 
    Filter chain halted as :correct_user rendered or redirected 
    Completed 302 Found in 6ms (ActiveRecord: 0.8ms) 

当它加载上面的项目,它加载AND "projects"."id" IS NULL LIMIT $2 - 为什么值NULL明确通过project_id3

回答

0

确定这是一个有点怪异。我固定它,通过执行以下操作:

routes.rb我改了行:

get "cancel" => 'projects#cancel' 

get "cancel", :on => :member 

这改变了我的路由。所以,当我rake routes,我现在的路线是这样的:

cancel_user_project GET /users/:user_id/projects/:id/cancel(.:format) projects#cancel 

这是现在与REST风格的寻路是一致的(如:用于编辑,路径是edit_user_project)。然后,我更新了我的链接如下:

旧的链接

<%= link_to 'Cancel', user_project_cancel_path(current_user, project) %> 

新干线

<%= link_to 'Cancel', cancel_user_project_path(current_user, project) %> 

而现在它的工作原理。仍然不完全确定为什么它对路由中的自定义动作不满意,但这显然是问题所在。

0

您可以检查以下关联的输出吗?

current_user.projects

+0

对不起,我仍然在学习钢轨 - 检查该关联输出的最佳方法是什么? – Stephen

+0

作为一个快速测试,我改变了'index'方法如下。而不是使用:@projects = Project.all.order(id::asc)',我使用了@projects = current_user.projects,并且在索引页上得到了相同的结果。它列出了所有的用户项目 – Stephen

+0

您可以使用rails console或通过pry gem进行调试。因此,如果您使用的是rails控制台,那么只需键入... User.find(id).projects ...这里传递用户的id,即当前用户ID。同时检查User类和Project类之间的关联。根据你的代码,它应该是User has_many projects和Project belongs_to user。让我知道你需要用admin_signed_in做什么?条件。 –