Class: RailsBestPractices::Prepares::ModelPrepare

Inherits:
Core::Check
  • Object
show all
Includes:
Core::Check::Accessable, Core::Check::Afterable, Core::Check::Classable
Defined in:
lib/rails_best_practices/prepares/model_prepare.rb

Overview

Remember models and model associations.

Constant Summary collapse

ASSOCIATION_METHODS =
%w(belongs_to has_one has_many has_and_belongs_to_many embeds_many embeds_one embedded_in many one)

Constants inherited from Core::Check

Core::Check::ALL_FILES, Core::Check::CONTROLLER_FILES, Core::Check::DEPLOY_FILES, Core::Check::HELPER_FILES, Core::Check::MAILER_FILES, Core::Check::MIGRATION_FILES, Core::Check::MODEL_FILES, Core::Check::PARTIAL_VIEW_FILES, Core::Check::ROUTE_FILES, Core::Check::SCHEMA_FILE, Core::Check::VIEW_FILES

Instance Method Summary collapse

Methods included from Core::Check::Afterable

included

Methods included from Core::Check::Accessable

#current_access_control, included

Methods included from Core::Check::Classable

#classable_modules, #current_class_name, #current_extend_class_name, included

Methods inherited from Core::Check

add_callback, #add_error, #after_review, callbacks, #errors, #increment_total_files_checked!, #interesting_files, interesting_files, interesting_nodes, #interesting_nodes, #method_missing, #node_end, #node_start, #parse_file?, #result, #total_files_checked, #url

Constructor Details

#initializeModelPrepare

Returns a new instance of ModelPrepare.



17
18
19
20
21
22
# File 'lib/rails_best_practices/prepares/model_prepare.rb', line 17

def initialize
  @models = Prepares.models
  @model_associations = Prepares.model_associations
  @model_attributes = Prepares.model_attributes
  @methods = Prepares.model_methods
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RailsBestPractices::Core::Check

Instance Method Details

#after_prepareObject

after prepare process, fix incorrect associations’ class_name.



110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rails_best_practices/prepares/model_prepare.rb', line 110

def after_prepare
  @model_associations.each do |model, model_associations|
    model_associations.each do |association_name, association_meta|
      unless @models.include?(association_meta["class_name"])
        if @models.include?("#{model}::#{association_meta['class_name']}")
          association_meta["class_name"] = "#{model}::#{association_meta['class_name']}"
        elsif @models.include?(model.gsub(/::\w+$/, ""))
          association_meta["class_name"] = model.gsub(/::\w+$/, "")
        end
      end
    end
  end
end

#start_alias(node) ⇒ Object

check alias node to remembr the alias methods.



104
105
106
107
# File 'lib/rails_best_practices/prepares/model_prepare.rb', line 104

def start_alias(node)
  method_name = node.new_method.to_s
  @methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
end

#start_class(node) ⇒ Object

remember the class name.



25
26
27
28
29
# File 'lib/rails_best_practices/prepares/model_prepare.rb', line 25

def start_class(node)
  if "ActionMailer::Base" != current_extend_class_name
    @models << @klass
  end
end

#start_command(node) ⇒ Object

check command node to remember all assoications or named_scope/scope methods.

the remembered association names (@associations) are like

{
  "Project" => {
    "categories" => {"has_and_belongs_to_many" => "Category"},
    "project_manager" => {"has_one" => "ProjectManager"},
    "portfolio" => {"belongs_to" => "Portfolio"},
    "milestones => {"has_many" => "Milestone"}
  }
}


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rails_best_practices/prepares/model_prepare.rb', line 80

def start_command(node)
  case node.message.to_s
  when *%w(named_scope scope alias_method)
    method_name = node.arguments.all.first.to_s
    @methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
  when "alias_method_chain"
    method, feature = *node.arguments.all.map(&:to_s)
    @methods.add_method(current_class_name, "#{method}_with_#{feature}", {"file" => node.file, "line" => node.line}, current_access_control)
    @methods.add_method(current_class_name, "#{method}", {"file" => node.file, "line" => node.line}, current_access_control)
  when "field"
    arguments = node.arguments.all
    attribute_name = arguments.first.to_s
    attribute_type = arguments.last.hash_value("type").present? ? arguments.last.hash_value("type").to_s : "String"
    @model_attributes.add_attribute(current_class_name, attribute_name, attribute_type)
  when "key"
    attribute_name, attribute_type = node.arguments.all.map(&:to_s)
    @model_attributes.add_attribute(current_class_name, attribute_name, attribute_type)
  when *ASSOCIATION_METHODS
    remember_association(node)
  else
  end
end

#start_def(node) ⇒ Object

check def node to remember all methods.

the remembered methods (@methods) are like

{
  "Post" => {
    "save" => {"file" => "app/models/post.rb", "line" => 10, "unused" => false, "unused" => false},
    "find" => {"file" => "app/models/post.rb", "line" => 10, "unused" => false, "unused" => false}
  },
  "Comment" => {
    "create" => {"file" => "app/models/comment.rb", "line" => 10, "unused" => false, "unused" => false},
  }
}


43
44
45
46
47
48
# File 'lib/rails_best_practices/prepares/model_prepare.rb', line 43

def start_def(node)
  if @klass && "ActionMailer::Base" != current_extend_class_name
    method_name = node.method_name.to_s
    @methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
  end
end

#start_defs(node) ⇒ Object

check defs node to remember all static methods.

the remembered methods (@methods) are like

{
  "Post" => {
    "save" => {"file" => "app/models/post.rb", "line" => 10, "unused" => false, "unused" => false},
    "find" => {"file" => "app/models/post.rb", "line" => 10, "unused" => false, "unused" => false}
  },
  "Comment" => {
    "create" => {"file" => "app/models/comment.rb", "line" => 10, "unused" => false, "unused" => false},
  }
}


62
63
64
65
66
67
# File 'lib/rails_best_practices/prepares/model_prepare.rb', line 62

def start_defs(node)
  if @klass && "ActionMailer::Base" != current_extend_class_name
    method_name = node.method_name.to_s
    @methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
  end
end