如何简化以下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
相关产品推荐
相关产品推荐

