You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何简化以下Ruby语言的update_agreement方法代码?

简化Ruby update_agreement 方法的可行方案

嘿,我来帮你简化这段代码!下面是几个能让代码更简洁、更贴合Ruby风格的方案,同时还能保持代码的可读性和可维护性:

方案1:提取重复逻辑到辅助方法

你会发现创建AgreementReading实例、设置用户属性的逻辑存在重复,把这些重复逻辑抽成小方法,能让主方法瞬间清爽很多:

def update_agreement(user = current_user)
  privacy_policy = Agreement.latest_active_privacy_policy.last
  terms_of_service = Agreement.latest_active_terms_of_service.last

  case params[:agreement_type]
  when "both"
    toggle_user_agreements(user, privacy: true, terms: true)
    log_agreement_reads(user, privacy_policy, terms_of_service)
  when "privacy"
    toggle_user_agreements(user, privacy: true)
    log_agreement_reads(user, privacy_policy)
  when "terms"
    toggle_user_agreements(user, terms: true)
    log_agreement_reads(user, terms_of_service)
  end

  # 这里可以补充用户和阅读记录的保存逻辑,比如 user.save!
end

private

def toggle_user_agreements(user, privacy: false, terms: false)
  user.privacy_policy = privacy if privacy
  user.terms_and_conditions = terms if terms
end

def log_agreement_reads(user, *agreements)
  agreements.each { |agreement| AgreementReading.new(user_id: user.id, agreement_id: agreement.id) }
end

方案2:用哈希映射替代case语句

如果agreement_type的分支不算多,用哈希来映射不同类型对应的操作,能让代码更紧凑、更易扩展:

def update_agreement(user = current_user)
  agreement_configs = {
    "both" => { privacy: true, terms: true, agreements: [Agreement.latest_active_privacy_policy.last, Agreement.latest_active_terms_of_service.last] },
    "privacy" => { privacy: true, agreements: [Agreement.latest_active_privacy_policy.last] },
    "terms" => { terms: true, agreements: [Agreement.latest_active_terms_of_service.last] }
  }

  return unless config = agreement_configs[params[:agreement_type]]

  user.privacy_policy = config[:privacy] if config.key?(:privacy)
  user.terms_and_conditions = config[:terms] if config.key?(:terms)
  
  config[:agreements].each do |agreement|
    AgreementReading.new(user_id: user.id, agreement_id: agreement.id)
  end
end

方案3:利用ActiveRecord关联简化记录创建

如果你的User模型和AgreementReading模型已经设置了关联(比如has_many :agreement_readings),可以直接用关联方法创建记录,省去手动传user_id的麻烦,还能整合保存逻辑:

# 先在User模型中添加关联:
# class User < ApplicationRecord
#   has_many :agreement_readings
# end

def update_agreement(user = current_user)
  privacy_policy = Agreement.latest_active_privacy_policy.last
  terms_of_service = Agreement.latest_active_terms_of_service.last

  case params[:agreement_type]
  when "both"
    user.update!(privacy_policy: true, terms_and_conditions: true)
    user.agreement_readings.create!(agreement_id: privacy_policy.id)
    user.agreement_readings.create!(agreement_id: terms_of_service.id)
  when "privacy"
    user.update!(privacy_policy: true)
    user.agreement_readings.create!(agreement_id: privacy_policy.id)
  when "terms"
    user.update!(terms_and_conditions: true)
    user.agreement_readings.create!(agreement_id: terms_of_service.id)
  end
end

这里用update!和create!会在操作失败时抛出异常,如果你不需要强校验,可以换成update和create。

内容的提问来源于stack exchange,提问作者ADMAT Bandara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:54:16