class Ecs::CreateCourseAchievementMethodsService < ApplicationService include AcceptsNestedAttributesHelper attr_reader :course_target, :params def initialize(course_target, params) @course_target = course_target @params = params end def call Ecs::CreateCourseAchievementMethodsForm.new( ec_course: course_target.ec_course, course_achievement_methods: params[:course_achievement_methods] ).validate! accepts_attributes = build_accepts_nested_attributes( course_target, course_target.ec_course_achievement_methods, params[:course_achievement_methods], &method(:deal_course_achievement_method_attribute!) ) course_target.assign_attributes(ec_course_achievement_methods_attributes: accepts_attributes) course_target.save! course_target end private def deal_course_achievement_method_attribute!(item) # 创建新的评价方法时,全部为新建 if item[:id].blank? || course_target.ec_course_achievement_methods.find_by(id: item[:id]).blank? item[:ec_achievement_evaluation_relates_attributes] = Array(*item[:course_evaluation_subitem_ids]).uniq.map do |subitem_id| { ec_course_evaluation_subitem_id: subitem_id.to_i } end return end achievement_method = course_target.ec_course_achievement_methods.find_by(id: item[:id]) relates = achievement_method.ec_achievement_evaluation_relates # 获取传入的 subitem id数组和已存在的 subitem id数组 old_subitem_ids = relates.map(&:ec_course_evaluation_subitem_id).uniq new_subitem_ids = Array(*item[:course_evaluation_subitem_ids]).map(&:to_i).uniq # 分别得到需要移除的 subitem ID数组和需要创建的 subitem ID数组 destroy_subitem_ids = old_subitem_ids - new_subitem_ids create_subitem_ids = new_subitem_ids - old_subitem_ids # 生成需要创建关系的 subitem id 数据 create_attributes = create_subitem_ids.map { |item_id| { ec_course_evaluation_subitem_id: item_id } } # 处理需要更新或者删除的记录 exists_attributes = relates.map do |relate| if destroy_subitem_ids.include?(relate.ec_course_evaluation_subitem_id) { id: relate.id, _destroy: true } else relate.as_json(only: %i[id ec_course_evaluation_subitem_id ec_course_achievement_method_id]) end end # 相加得到accepts_nested_attributes item[:ec_achievement_evaluation_relates_attributes] = create_attributes + exists_attributes end end