lib/can_be/processor/instance.rb in can_be-0.2.1 vs lib/can_be/processor/instance.rb in can_be-0.3.0

- old
+ new

@@ -3,24 +3,36 @@ class Instance def initialize(model) @model = model @config = model.class.can_be_config @field_name = @config.field_name + @details_name = @config.details_name.to_sym + @details_id = "#{@details_name}_id".to_sym + @details_type = "#{@details_name}_type".to_sym + set_cleaning_defaults end def boolean_eval(t) - field_value == t + field_value.to_s == t.to_s end - def update_field(t, save = false) + def update_field(t, options = {}) + @original_details = @model.send(@details_name) + @force_history_removal = options[:force_history_removal] if options.has_key?(:force_history_removal) + + save = options.has_key?(:save) ? options[:save] : false + if save - original_details = @model.details @model.update_attributes(@field_name => t) - original_details.destroy unless original_details.class == @model.details.class else self.field_value = t end + + if block_given? + yield(@model.send(@details_name)) + @model.send(@details_name).save if save + end end def field_value=(t) set_details(t) @model.send(:write_attribute, @field_name, t) @@ -33,28 +45,111 @@ def set_default_field_value self.field_value = @config.default_type if self.field_value.nil? end def initialize_details - set_details(field_value.to_sym) if has_details? && !@model.details_id + set_details(field_value.to_sym) if has_details? && !@model.send(@details_id) end + def clean_details + if @original_details && @original_details.class != @model.send(@details_name).class + if @config.keeps_history? + if @force_history_removal + @original_details.destroy + destroy_history(@original_details.class.name.underscore) + end + else + @original_details.destroy + end + end + + set_cleaning_defaults + end + + def set_cleaning_defaults + @original_details = nil + @force_history_removal = false + end + + def save_history + history_model_class.create({ + can_be_model_id: @model.id, + can_be_type: field_value, + can_be_details_id: @model.send(@details_name).id, + can_be_details_type: details_class_name(field_value) + }) unless history_model_for(field_value) + end + + def destroy_histories + histories = history_model_class.where(can_be_model_id: @model.id) + + destroy_details_history(histories) + histories.destroy_all + end + + def destroy_history(details_type) + history_model_class.where(can_be_model_id: @model.id, can_be_details_type: details_type).destroy_all + end + private def has_details? - @model.respond_to?(:details) && @model.respond_to?(:details_id) && @model.respond_to?(:details_type) + @model.respond_to?(@details_name) && @model.respond_to?(@details_id) && @model.respond_to?(@details_type) end def set_details(t) return unless has_details? - classname = @config.details[t.to_sym] + if details_class_name(t) + if @config.keeps_history? + set_history_details_for(t) + else + @model.send("#{@details_name}=", details_for(t)) + end + else + @model.send("#{@details_id}=", nil) + @model.send("#{@details_type}=", nil) + end + end - if classname - @model.details = classname.to_s.camelize.constantize.new + def destroy_details_history(histories) + histories.each do |h| + details_record = details_class(h.can_be_type).where(id: h.can_be_details_id).first + details_record.destroy if details_record + end + end + + def set_history_details_for(t) + history_model = history_model_for(t) + + if history_model + @model.send("#{@details_name}=", details_for(t, history_model.can_be_details_id)) else - @model.details_id = nil - @model.details_type = nil + @model.send("#{@details_name}=", details_for(t)) end + end + + def details_for(t, details_id = nil) + if details_id.nil? + details_class(t).new + else + details_class(t).find(details_id) + end + end + + def history_model_for(t) + history_model_class.where(can_be_model_id: @model.id, can_be_type: t).first + end + + def details_class_name(t) + @config.details[t.to_sym] + end + + def details_class(t) + details_class_name(t).to_s.camelize.constantize if details_class_name(t) + end + + def history_model_class + @config.history_model.to_s.camelize.constantize end end end end