Module: OpenStax::Utilities::ActsAsNumberable
- Included in:
- ActiveRecord::Base
- Defined in:
- lib/openstax/utilities/acts_as_numberable.rb
Defined Under Namespace
Modules: BasicInstanceMethods, ContainerInstanceMethods
Instance Method Summary collapse
-
#acts_as_numberable(options = {}) ⇒ Object
Adds code to an ActiveRecord object so that it can be sorted.
Instance Method Details
#acts_as_numberable(options = {}) ⇒ Object
Adds code to an ActiveRecord object so that it can be sorted.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/openstax/utilities/acts_as_numberable.rb', line 32 def acts_as_numberable(={}) configuration = {} configuration.update() if .is_a?(Hash) container_column = nil container_column_symbol = nil # When calling assign_number below, you normally want to run a query against # self.class to figure out what the next available number is; however, if the # class acting as numberable is using STI, self.class will return the child class # which is likely not what we want. In these cases, we can specify the base # class here (the class that has the same name as the DB table) so that it is used # instead. table_class = configuration[:table_class] number_field = (configuration[:number_field] || 'number').to_s if !configuration[:container].nil? container_column = configuration[:container].to_s + "_id" container_column_symbol = configuration[:container].to_sym end uniqueness_scope_string = container_column.nil? ? "" : ":scope => :#{container_column}," class_eval " include ActsAsNumberable::BasicInstanceMethods\n \n before_validation :assign_number, :on => :create\n \n validates :\#{number_field}, :uniqueness => { \#{uniqueness_scope_string}\n :allow_nil => true},\n :numericality => { :only_integer => true, \n :greater_than_or_equal_to => 0,\n :allow_nil => true } \n\n \n after_destroy :mark_as_destroyed\n \n attr_accessor :destroyed\n attr_accessor :changed_sets\n\n attr_protected :\#{number_field}\n \n scope :ordered, order('\#{number_field} ASC')\n scope :reverse_ordered, order('\#{number_field} DESC')\n \n def self.sort!(sorted_ids)\n return if sorted_ids.blank?\n items = []\n ActiveRecord::Base.transaction do\n items = find_in_specified_order(sorted_ids)\n \n items.each do |item|\n item.send('\#{number_field}=', nil)\n item.save!\n end\n \n items.each_with_index do |item, ii| \n item.send('\#{number_field}=', ii)\n item.save!\n end\n end\n items\n end\n\n def table_class\n \#{table_class}\n end\n\n def number_field\n '\#{number_field}'\n end\n EOV\n \n \n if !configuration[:container].nil?\n class_eval <<-EOV\n include ActsAsNumberable::ContainerInstanceMethods\n \n # When we had nested acts_as_numberables, there were cases where the\n # objects were having their numbers changed (as their peers were being\n # removed from the container), but then when it came time to delete those \n # objects they still had their old number. So just reload before\n # destroy.\n before_destroy(prepend: true) {self.reload}\n \n after_destroy :remove_from_container!\n \n def container_column\n '\#{container_column}'\n end\n\n def container\n '\#{configuration[:container]}'\n end\n\n def table_class\n \#{table_class}\n end\n \n EOV\n \n end\n \nend\n" |