使用draper gem和设计注册控制器

时间:2016-04-20 09:53:20

标签: ruby-on-rails ruby devise draper

我已按以下方式声明user_decorator.rb而不是user_helper.rb

class UserDecorator < Draper::Decorator
   delegate_all

  def contract_type
    contract_types.keys.collect {|k| [k.humanize, k]}
  end
  def employee_type
    employee_types.keys.collect {|k| [k.humanize, k]}
  end

  def department_role
    department_roles.keys.collect {|k| [k.humanize, k]}
  end
end

以下是我在user.rb上声明的枚举

 enum contract_type: [:probationary, :apprenticeship, :six_months_to_one_year,
    :three_years]
  enum department_role: [:ceo, :cto, :coo, :manager, :tl, :gl, :developer]
  enum employee_type: [:full_time, :part_time, :internship]

我想从与注册控制器相关的视图中调用辅助方法。它就像

class RegistrationsController < Devise::RegistrationsController

  def new
    super
  end

  def create
    super
  end
end

但是如果我调用helper方法,就像下面的views / devise / registrations / new.html.erb

一样
<%= f.select :contract_type, contract_type, {prompt: t(".contract_type",
      default: "Select contract type")} %>

找不到contract_type。需要有关如何从user_decorator.rb上声明的视图访问辅助方法的帮助

2 个答案:

答案 0 :(得分:0)

为了从Devise的current_user方法获取装饰的用户对象,you can override it

class ApplicationController < ActionController::Base
  def current_user
    UserDecorator.decorate(super) unless super.nil?
  end
end

但是,由于您的问题出现在devise/registrations/new.html.erb页面上,此时用户将无法登录,因此无法获得任何类型的装饰current_user对象。

所以,你想要的是将你的User模型中的一组装饰合同类型放到该视图中,你可以通过在控制器上创建一个实例变量来实现:

class RegistrationsController < Devise::RegistrationsController
  def new
    @contract_types = User.contract_types.keys.collect {|k| [k.humanize, k]}
    super
  end
end

然后在视图中使用它:

<%= f.select :contract_type, 
             @contract_types,
             { prompt: t(".contract_type", default: "Select contract type") } %>

如果您想进行进一步的重构,您可以在User模型上创建一个类似范围的类方法来处理合同类型:

class User < ActiveRecord::Base
  def self.humanized_contract_types
    contract_types.keys.collect {|k| [k.humanize, k]}
  end
end

因此,您的控制器代码可以缩短为:

class RegistrationsController < Devise::RegistrationsController
  def new
    @contract_types = User.humanized_contract_types
    super
  end
end

或者,如果您打算使用UserDecorator课程,则可以查看proxying class method calls to it

答案 1 :(得分:0)

您可以覆盖callback方法来装饰您的资源,如下所示:

new