I-de-ya/ideyabox

View on GitHub
lib/ar_ideyabox.rb

Summary

Maintainability
A
1 hr
Test Coverage
module ArIdeyabox
  # In model just add this line
  # has_not_this :person, through: :professions_people, order: :title, by: :title, group_by: {play: :title}
  # :order and :by - optionally
  # :group_by is for group selectors, if you want grouping roles by play titles, just add group_by: {play: :title}
  
  def visible
    where(visible: true)
  end

  def by_position
    order(:position)
  end

  def visible_by_position
    visible.by_position
  end

  def first_el_tryer(object, by)
    if by.class == Hash
      object.try(by.keys[0]).try(by.values[0])
    else
      object.try(by)
    end
  end

  def has_not_this(model_name, *args)
    options = args.extract_options!
    join_model = options[:through].to_s.singularize.camelize
    self_id_sym = "#{self.to_s.underscore}_id".to_sym
    array_first_el = options[:by] ? options[:by] : :title
    group_by = options[:group_by]
    includes = options[:includes]
    model_name_id = "#{model_name}_id"

    define_singleton_method("has_not_this_#{model_name}") do |ids|
      excluded_ids = join_model.constantize.where(model_name_id.to_sym => ids).collect(&self_id_sym)
      output = self.where{id << excluded_ids}
      output = output.includes(includes) if includes
      output = output.order(options[:order]) if options[:order]
      if group_by
        output = output.group_by{|a| first_el_tryer(a, group_by)} 
        output.delete(nil)
        output.each do |key, value|
          array = []
          value.each do |el|
            array << [first_el_tryer(el, array_first_el), el.id]
          end
          output[key] = array
        end
        # output.to_a.sort
      else
        output.collect{|p| [first_el_tryer(p, array_first_el), p.id]}
      end
    end
  end
  
  # Original method for one model looks like this
  # def self.has_not_this_person(person_id)
  #   excluded_ids = ProfessionsPerson.where(person_id: person_id).collect(&:profession_id)
  #   self.where{id << excluded_ids}.order(:title).collect{|p| [p.title, p.id]}
  # end
end

ActiveSupport.on_load :active_record do
  extend ArIdeyabox
end