module PrettyAssociationInspect
モデルに関連情報を見やすく表示するメソッドを定義します。
Constants
- VERSION
Public Instance Methods
all_models_define()
click to toggle source
全てのモデルにメソッドを定義する
# File lib/pretty_association_inspect.rb, line 217 def all_models_define model_names_array = load_all_models model_names_array.each do |model_name| begin klass = eval(model_name) pretty_association_inspect_define(klass) rescue next end end end
build_association_hash(model)
click to toggle source
アソシエーションをハッシュに変換
# File lib/pretty_association_inspect.rb, line 157 def build_association_hash(model) pretty_hash = model.reflect_on_all_associations.each_with_object({}) do |m, hash| name = m.class.to_s.gsub("ActiveRecord::Reflection::", "").gsub("Reflection", "").to_sym hash[name] ||= [] human_name = PrettyAssociationInspect.jp_scripe(m.klass.model_name.human) hash[name] << [ m.name, human_name ].compact.join(' | ') hash[name] = hash[name] end end
build_association_node(start, max_cost)
click to toggle source
# File lib/pretty_association_inspect.rb, line 80 def build_association_node(start, max_cost) models = ActiveRecord::Base.subclasses.map(&:name) data = models.each_with_object({}) do |model_name_str, hash| eval(model_name_str).reflect_on_all_associations.each do |m| model_single_name = eval(model_name_str).model_name.singular.to_sym model_multiple_name = eval(model_name_str).model_name.plural.to_sym hash[model_single_name] ||= [] hash[model_multiple_name] ||= [] hash[model_single_name] << [1, m.name] hash[model_multiple_name] << [1, m.name] end end graph = Graph.new(data) route_hash = {} data.each do |goal, v| next if start == goal new_route = graph.print_route(graph.minimum_route(start, goal, max_cost)) _model_ = ActiveRecord::Base.module_eval(goal.to_s.camelize.singularize).model_name.human rescue nil human_str = PrettyAssociationInspect.jp_scripe(_model_) route_hash["#{goal} #{human_str}"] = new_route if new_route end route_hash end
jp_scripe(str)
click to toggle source
日本語だけ抽出
# File lib/pretty_association_inspect.rb, line 211 def jp_scripe(str) japanese = Regexp.new(/[亜-熙ぁ-んァ-ヶ]/) str if japanese =~ str end
load_all_models()
click to toggle source
全てのモデルを読み込み、モデル名配列を返す
# File lib/pretty_association_inspect.rb, line 230 def load_all_models models_file_path = Dir.glob(Rails.root.join("app/models/*")).grep(/rb\z/) models_file_path.each { |m| require(m) rescue next } return ActiveRecord::Base.subclasses.map(&:name) end
pretty_association_inspect_define(klass)
click to toggle source
『関連を可愛く表示するメソッド』を定義する
# File lib/pretty_association_inspect.rb, line 106 def pretty_association_inspect_define(klass) klass.class_eval do |model| self.define_singleton_method(:to){ associations_hash = PrettyAssociationInspect.build_association_hash(model) PrettyAssociationInspect.printed(klass, model, associations_hash) return self.first || self } define_method(:to){ associations_hash = PrettyAssociationInspect.build_association_hash(model) PrettyAssociationInspect.printed(klass, model, associations_hash) return self } self.define_singleton_method(:toto){ |max_cost=1, start = nil| model_name_sym = model_name.singular.to_sym route_arr = PrettyAssociationInspect.build_association_node(start || model_name_sym, max_cost) ap route_arr.map { |route| [route.first, eval(route.last.to_s)] rescue nil } ap route_arr return nil } define_method(:toto){ |max_cost = 1, start = nil| model_name_sym = model_name.singular.to_sym route_arr = PrettyAssociationInspect.build_association_node(start || model_name_sym, max_cost) ap route_arr.map { |route| [route.first, eval(route.last.to_s)] rescue nil } ap route_arr return nil } self.define_singleton_method(:s){ |name = nil| results = Module.const_get(self.to_s).columns.select{|m| m.sql_type=~/char/}.map(&:name).map(&:to_sym).each_with_object([]) { |attr, records| result = self.where(self.arel_table[attr].matches("%#{name}%")) records << [attr, result.ids, result] }.select{|m| m.second.present? } ap results result_where = self.where(id: results.map(&:second).flatten) ap result_where return result_where } end end
printed(klass, model, associations_hash)
click to toggle source
表示
# File lib/pretty_association_inspect.rb, line 170 def printed(klass, model, associations_hash) pretty_hash = {} begin klass.class_eval{|klass| klass.first.attributes.each{|k ,v| pretty_hash[k.to_sym] = [ PrettyAssociationInspect.value_convert(k, v, klass), PrettyAssociationInspect.jp_scripe(klass.human_attribute_name(k)), v ].compact.join(' | ') } } rescue => e ap e end ap "-"*100; ap "#{klass.name} #{jp_scripe(klass.model_name.human)}" ap "[クラスメソッド]" base_pattern = "(before|after|around)_(add|remove|restore)|_associated_records_for_|inherited" extr_pattern = "attribute_type_decorations|soft_de|_restore_callback|indexed_|_by_resource" delete_pattern = Regexp.new( [ base_pattern, extr_pattern ].join('|') ) class_m = model.methods(false) - model.instance_methods ap (class_m).delete_if{|name| delete_pattern.match(name) }.sort ap "[インスタンスメソッド]" instance_m = model.instance_methods(false) - model.superclass.instance_methods ap (instance_m).delete_if{|name| delete_pattern.match(name) }.sort ap "[バリデーション]" ap model.validators.map{|m| m.class.name.gsub(/Active|Record|Validations|Model|Validator|::/,"") .concat(" #{m.attributes.join(', ')} #{m.options}") }.sort.uniq ap "[アソシエーション]" ap associations_hash ap "[詳細]" ap pretty_hash ap "-"*100 end
value_convert(k, v, klass)
click to toggle source
バリューを整形
# File lib/pretty_association_inspect.rb, line 147 def value_convert(k, v, klass) klass.class_eval { return columns_hash[k.to_s].type if v.blank? is_e = Object.const_defined?(:Enumerize) && first.send(k).kind_of?(Enumerize::Value) return "#{v} #{first.send(k).text} #{send(k).values} #{send(k).values.map(&:text)}" if is_e return v.strftime("%y年%m月%d日 %H:%M") if v.respond_to?(:strftime) } end