控制器模型特定或行动特定?

时间:2017-05-10 21:00:56

标签: ruby-on-rails model controller

假设您有以下内容。

Manager model
Request model
User model

A user makes a request. The manager then approves that request (or denies it).

所以我的问题是:批准/拒绝方法是否进入请求控制器或管理器控制器?或者也许没关系?

经理执行“操作”,但在后台我们正在更新模型。它可以像改变字符串一样简单。

我已经做到了这两种方式,对我来说更具模特性似乎更自然,但我想以正确的方式做到这一点,因为我还没有完成大量的项目。

1 个答案:

答案 0 :(得分:1)

class User < ApplicationRecord
  enum role: [:employee, :manager]
  has_many :applications, foreign_key: 'applicant_id'
end

class Application < ApplicationRecord
  belongs_to :applicant, class_name: 'User'
  has_many :approvals
end

class Approval < ApplicationRecord
  belongs_to :application
  belongs_to :manager, class: 'User'
  validates_uniqueness_of :application_id, scope: 'manager_id'
end

注意Application而不是RequestRequestResponse作为模型名称存在问题,因为它们通常是Rails和Web开发中的核心概念。例如,使用实例变量@request将屏蔽传入的请求!它也使你的代码很难推理。

请注意,除非要求完全不同,否则您可能不需要单独的经理模型。您可以使用roles来解决此问题。

然后我们设置一个嵌套路线:

resources :applications do
  resources :approvals, only: [:create, :destroy], shallow: true
end

CRUD批准的控制器:

class ApprovalsController < ApplicationController

  before_action :authenticate_user!   
  before_action :authorize! 
  before_action :set_application, only: [:new, :create, :index]  

  # Approve an application
  # POST /applications/:application_id/approvals
  def create
    @approval = @application.approvals.new do |a|
      a.manager = current_user
    end
    if @approval.save
      redirect_to @application, success: 'Application Approved'
    else
      render :new
    end
  end

  # Revoke approval
  # DELETE /approvals/:id
  def destroy
    @approval = Approval.find(params[:id])
    @approval.destroy
    redirect_to @approval.application, success: 'Approval revoked.'
  end

  private
  def set_application
    @application = Application.find(params[:application_id])
  end

  # Just a minimal authorization example
  # Use Pundit or CanCanCan for real world apps instead of reinventing the wheel
  def authorize!
    raise AuthorizationError unless current_user.manager?
  end
end