如何使这段代码ruby代码更简单?

时间:2018-03-20 06:37:56

标签: ruby-on-rails

def update_agreement
 user = current_user
 privacy_policy_agreement = Agreement.latest_active_privacy_policy.last
 terms_of_service_agreement = Agreement.latest_active_terms_of_service.last

case params[:agreement_type]
when "both"
  user.privacy_policy = true
  user.terms_and_conditions = true
  read_privacy_policy = AgreementReading.new(user_id: user.id, agreement_id: privacy_policy_agreement.id)
  read_terms_of_service = AgreementReading.new(user_id: user.id, agreement_id: terms_of_service_agreement.id)
  save_and_finished =  user.save && read_privacy_policy.save && read_terms_of_service.save
when "privacy_policy"
  user.privacy_policy = true
  read_privacy_policy = AgreementReading.new(user_id: user.id, agreement_id: privacy_policy_agreement.id)
  save_and_finished =  user.save && read_privacy_policy.save
when "terms_of_service"
  user.terms_and_conditions = true
  read_terms_of_service = AgreementReading.new(user_id: user.id, agreement_id: terms_of_service_agreement.id)
  save_and_finished = user.save && read_terms_of_service.save
end

if save_and_finished
  render json: { success: true }
else
  render json: { success: false }, status: :internal_server_error
end
end

我使用上面的代码来管理用户和协议。我觉得这段代码不是那么体面。你的想法是什么 ?怎么做这个干?

1 个答案:

答案 0 :(得分:0)

您可以将逻辑从控制器移到普通红宝石对象

这是一个快速未测试的样本提取版本

def update_agreement
  if AgreementUpdaterService.new(current_user, params).call
    render json: { success: true }
  else
    render json: { success: false }, status: :internal_server_error #FIXME use appropriate error code
  end
end

class AgreementUpdaterService
  def new(user, params)
    @user = user
    @params = params
  end

  def call
    case params[:agreement_type]
    when 'both'
      accept_privacy_policy! && accept_terms_and_service!
    when 'privacy_policy'
      accept_privacy_policy!
    when 'terms_of_service'
      accept_terms_and_service!
    end
  end

  private

  attr_accessor :user, :params

  def accept_privacy_policy!
    User.transaction do
      user.privacy_policy = true
      read_privacy_policy = AgreementReading.new(user_id: user.id, agreement_id: privacy_policy_agreement.id)
      user.save
      read_privacy_policy.save
    end
  end

  def accept_terms_and_service!
    User.transaction do
      user.terms_and_conditions = true
      #TODO add an association from User to AgreementReading
      read_terms_of_service = AgreementReading.new(user_id: user.id, agreement_id: terms_of_service_agreement.id)
      user.save
      read_terms_of_service.save
    end
  end

  def privacy_policy_agreement
    @_privacy_policy_agreement ||= Agreement.latest_active_privacy_policy.last #TODO do we really need last here ?
  end

  def terms_of_service_agreement
    @_terms_of_service_agreement ||= Agreement.latest_active_terms_of_service.last
  end
end