<commit_before>class ArtefactsController < ApplicationController
  before_filter :redirect_to_show_if_need_met, :only => :new
  before_filter :find_artefact, :only => [:show, :edit, :update]
  before_filter :build_artefact, :only => [:new, :create]
  before_filter :mark_unused_related_items_for_destruction, :only => :update

  def show
    respond_to do |format|
      format.js do # TODO use format.json
        # TODO extract presenter
        render :json =>
          @artefact.as_json(
            :include => {
              :audiences      => {},
              :related_items  => { :include => :artefact }, # TODO use :related_artefacts => {}
              :contacts       => {}
            }
          )
      end

      format.html { redirect_to @artefact.admin_url }
    end
  end

  def new
  end

  def edit
  end

  def create
    if @artefact.save
      destination = @artefact.admin_url
      destination += '?return_to=' + params[:return_to] if params[:return_to]
      redirect_to destination
    else
      render :new
    end
  end

  def update
    if @artefact.update_attributes(params[:artefact])
      redirect_to @artefact
    else
      render :edit
    end
  end

  private
    def redirect_to_show_if_need_met
      artefact = Artefact.find_by_need_id params[:artefact][:need_id]
      redirect_to artefact if artefact.present?
    end

    def find_artefact
      @artefact = Artefact.from_param(params[:id])
    end

    def build_artefact
      @artefact = Artefact.new(params[:artefact])
    end

    def mark_unused_related_items_for_destruction
      params[:artefact][:related_items_attributes].each_value do |attributes|
        attributes[:_destroy] = attributes[:id].present? && attributes[:artefact_id].blank?
      end
    end
end<commit_msg>Generalise mark_unused_related_items_for_destruction for other associations<commit_after>class ArtefactsController < ApplicationController
  before_filter :redirect_to_show_if_need_met, :only => :new
  before_filter :find_artefact, :only => [:show, :edit, :update]
  before_filter :build_artefact, :only => [:new, :create]
  before_filter :mark_removed_records_for_destruction, :only => :update

  def show
    respond_to do |format|
      format.js do # TODO use format.json
        # TODO extract presenter
        render :json =>
          @artefact.as_json(
            :include => {
              :audiences      => {},
              :related_items  => { :include => :artefact }, # TODO use :related_artefacts => {}
              :contacts       => {}
            }
          )
      end

      format.html { redirect_to @artefact.admin_url }
    end
  end

  def new
  end

  def edit
  end

  def create
    if @artefact.save
      destination = @artefact.admin_url
      destination += '?return_to=' + params[:return_to] if params[:return_to]
      redirect_to destination
    else
      render :new
    end
  end

  def update
    if @artefact.update_attributes(params[:artefact])
      redirect_to @artefact
    else
      render :edit
    end
  end

  private
    def redirect_to_show_if_need_met
      artefact = Artefact.find_by_need_id params[:artefact][:need_id]
      redirect_to artefact if artefact.present?
    end

    def find_artefact
      @artefact = Artefact.from_param(params[:id])
    end

    def build_artefact
      @artefact = Artefact.new(params[:artefact])
    end

    def mark_removed_records_for_destruction
      [:related_artefacts].each do |association|
        reflection = Artefact.reflect_on_association association
        through_association, foreign_key = reflection.through_reflection.name, reflection.foreign_key

        mark_associated_records_for_destruction through_association,
          :if => -> attributes { attributes[foreign_key].blank? }
      end
    end

    def mark_associated_records_for_destruction(association, options)
      primary_key = Artefact.reflect_on_association(association).active_record_primary_key

      params[:artefact][:"#{association}_attributes"].each_value do |attributes|
        attributes[:_destroy] = attributes[primary_key].present? && options[:if].call(attributes)
      end
    end
end
{'fraction_non_alphanumeric': 0.08966346153846154, 'fraction_numerical': 0.0, 'mean_word_length': 2.8815298507462686, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7306022', 'n_tokens_mistral': 1269, 'n_tokens_neox': 1282, 'n_words': 265}