Collection of concerns for your Rails application
Copy to your app/models/concerns directory
Use and modificate at your will. Fork this gist to participate.
@romansklenar
| module Paranoid | |
| extend ActiveSupport::Concern | |
| included do | |
| extend ClassMethods | |
| include InstanceMethods | |
| scope :only_deleted, -> { unscoped.where.not(deleted_at: nil) } | |
| scope :with_deleted, -> { unscoped } | |
| scope :without_deleted, -> { where(deleted_at: nil) } | |
| default_scope { without_deleted } | |
| end | |
| module ClassMethods | |
| def restore(id) | |
| if id.is_a?(Array) | |
| id.map { |one_id| restore(one_id) } | |
| else | |
| only_deleted.find(id).restore! | |
| end | |
| end | |
| end | |
| module InstanceMethods | |
| def destroy! | |
| run_callbacks(:destroy) { delete! } | |
| end | |
| alias :destroy :destroy! | |
| def delete! | |
| return if new_record? || destroyed? | |
| self.class.unscoped { update_column :deleted_at, Time.now } | |
| end | |
| alias :delete :delete! | |
| def restore! | |
| self.class.unscoped { update_column :deleted_at, nil } | |
| end | |
| alias :restore :restore! | |
| def destroyed? | |
| !self.deleted_at.nil? | |
| end | |
| alias :deleted? :destroyed? | |
| def paranoid? | |
| true | |
| end | |
| # If a paranoid record is selected, then we only want to check | |
| # if it's a new record, not if it is "destroyed". | |
| def persisted? | |
| paranoid? ? !new_record? : super | |
| end | |
| end | |
| end |
| module Steppable | |
| extend ActiveSupport::Concern | |
| included do | |
| include InstanceMethods | |
| attr_writer :steps, :current_step | |
| end | |
| module ClassMethods | |
| end | |
| module InstanceMethods | |
| def steps | |
| @step ||= [] | |
| end | |
| def current_step | |
| @current_step ||= steps.first | |
| end | |
| def next_step | |
| steps[steps.index(current_step)+1] unless last_step? && steps.any? | |
| end | |
| def previous_step | |
| steps[steps.index(current_step)-1] unless first_step? && steps.any? | |
| end | |
| def first_step | |
| steps.first | |
| end | |
| def last_step | |
| steps.last | |
| end | |
| def skip_step! | |
| @current_step = next_step | |
| end | |
| def current_step?(step) | |
| current_step == step | |
| end | |
| def next_step?(step) | |
| steps[steps.index(step)] == next_step if steps.include?(step) | |
| end | |
| def previous_step?(step) | |
| steps[steps.index(step)] == previous_step if steps.include?(step) | |
| end | |
| def first_step?(step = nil) | |
| (step || current_step) == first_step | |
| end | |
| def last_step?(step = nil) | |
| (step || current_step) == last_step | |
| end | |
| def progress | |
| i = steps.index(current_step) | |
| (i+1).to_f / steps.size * 100 if steps.any? | |
| end | |
| end | |
| end |
| module Taggable | |
| extend ActiveSupport::Concern | |
| included do | |
| include InstanceMethods | |
| has_many :taggings, as: :taggable, dependent: :destroy | |
| has_many :tags, through: :taggings | |
| end | |
| module InstanceMethods | |
| def tag(name) | |
| name.strip! | |
| tag = Tag.where(name: name).first_or_create! | |
| self.taggings.where(tag: tag).first_or_create! | |
| end | |
| def tag_names | |
| @tag_names ||= tags.collect(&:name).flatten.uniq.join(Tag::DELIMITER) | |
| end | |
| def tag_names=(names) | |
| self.taggings.destroy_all | |
| names.strip.split(Tag::DELIMITER).flatten.uniq.each { |name| self.tag(name) } | |
| end | |
| end | |
| end |
| module Tagger | |
| extend ActiveSupport::Concern | |
| included do | |
| include InstanceMethods | |
| has_many :owned_taggings, as: :tagger, dependent: :destroy, class_name: "Tagging" | |
| has_many :owned_tags, through: :owned_taggings, source: :tag, class_name: "Tag" | |
| end | |
| module InstanceMethods | |
| def tag(taggable, with) | |
| tag_names = with.flatten.uniq.map(&:strip) | |
| tag_names.each do |name| | |
| tag = Tag.where(name: name).first_or_create! | |
| self.owned_taggings.where(tag: tag, taggable: taggable, tagger: self).first_or_create! | |
| end | |
| end | |
| def owned_tag_names | |
| owned_tags.pluck(:name).flatten.uniq.join(Tag::DELIMITER) | |
| end | |
| end | |
| end |