module SetFrom::ClassMethods
school = School.create teacher = Teacher.create(school: school) course = teacher.courses.create course.school_id # => school.id
Public Instance Methods
set_from(source, options={})
click to toggle source
# File lib/set_from.rb, line 30 def set_from(source, options={}) targets = options.fetch(:targets, []) if targets.last.is_a?(Hash) hash_params = targets.pop targets_hash = Hash[targets.map{|key| [key, key]}] targets_hash = targets_hash.merge(hash_params) else targets_hash = Hash[targets.map{|key| [key, key]}] end update_for_change = options.fetch(:update_for_change, false) prefix = options.fetch(:prefix, false) self.class_eval do after_initialize "set_from_#{source}".to_sym, if: :new_record? before_validation "set_from_#{source}".to_sym, if: :new_record? if update_for_change before_save "set_from_#{source}_when_change".to_sym, if: ->{ persisted? && send("#{source.to_s.foreign_key}_changed?")} end define_method "set_from_#{source}".to_sym do from_source = self.send(source) targets_hash.each do |source_target_method, set_target_method| set_target_method = prefix ? "#{source}_#{set_target_method}" : set_target_method if self.respond_to?(set_target_method) && self.send(set_target_method).blank? && from_source.present? && from_source.respond_to?(source_target_method) self.send("#{set_target_method}=", from_source.send(source_target_method)) end end end define_method "set_from_#{source}_when_change".to_sym do from_source = self.send(source) targets_hash.each do |source_target_method, set_target_method| set_target_method = prefix ? "#{source}_#{set_target_method}" : set_target_method if self.respond_to?(set_target_method) && from_source.present? && from_source.respond_to?(source_target_method) self.send("#{set_target_method}=", from_source.send(source_target_method)) end end end end end