class Schofield::Generators::Level

Constants

COLUMNS_TO_IGNORE

Attributes

columns_to_ignore[R]
attributes[R]
child_associations[RW]
model[R]
name[R]
parent_associations[R]
subclasses[RW]
superclass[R]

Public Class Methods

new(model, superclass=nil) click to toggle source
# File lib/generators/schofield/level.rb, line 33
def initialize model, superclass=nil
  @model               = model
  @name                = model.name.underscore
  @human_name          = @name.gsub('_', ' ')
  @superclass          = superclass
  @subclasses          = []
  @parent_associations = []
  @child_associations  = []
  add_parent_associations
  add_attributes
end
tables_to_ignore=(tables) click to toggle source
# File lib/generators/schofield/level.rb, line 11
def self.tables_to_ignore= tables
  @columns_to_ignore = ( COLUMNS_TO_IGNORE + tables.map{ |m| "^#{m.singularize}_id$" } )
end

Public Instance Methods

ancestry() click to toggle source

Association ancestry

# File lib/generators/schofield/level.rb, line 173
def ancestry
  level = self
  nested_ins = []
  next_name = nil
  while level
    if next_name
      this_name = next_name
      next_name = nil
    else
      this_name = level.name
    end
    nested_ins << this_name
    next_name = level.polymorphic_name if level.polymorphic?
    level = level.parent_associations.select(&:nest?).map(&:parent).first
    # polymorphic model could have more than one parent!!!
  end
  nested_ins.reverse
end
attribute_of_nesting_parent?(attribute) click to toggle source

Form fields

# File lib/generators/schofield/level.rb, line 195
def attribute_of_nesting_parent? attribute
  attribute.model_name && parent_associations.select(&:nest?).map(&:parent_name).include?(attribute.model_name)
end
belongs_to?() click to toggle source

Associations and cardinality

# File lib/generators/schofield/level.rb, line 104
def belongs_to?
  @parent_associations.any?
end
belongs_to_one?() click to toggle source
# File lib/generators/schofield/level.rb, line 112
def belongs_to_one?
  @parent_associations.any?(&:one_to_one?)
end
belongs_to_one_names() click to toggle source
# File lib/generators/schofield/level.rb, line 108
def belongs_to_one_names
  @parent_associations.select(&:one_to_one?).map(&:parent_name)
end
controllers?() click to toggle source
# File lib/generators/schofield/level.rb, line 139
def controllers?
  !superclass? && name != 'user' && !belongs_to_one?
end
form_field?(attribute) click to toggle source
# File lib/generators/schofield/level.rb, line 203
def form_field? attribute
  !%w( position slug ).include?(attribute.name) && attribute.name !~ /_fingerprint$/ && !polymorphic_attribute?(attribute) && !attribute_of_nesting_parent?(attribute)
end
has_manies() click to toggle source
# File lib/generators/schofield/level.rb, line 128
def has_manies
  @child_associations.select(&:one_to_many?).map(&:child)
end
has_manies?() click to toggle source
# File lib/generators/schofield/level.rb, line 120
def has_manies?
  @child_associations.any?(&:one_to_many?)
end
has_ones() click to toggle source
# File lib/generators/schofield/level.rb, line 124
def has_ones
  @child_associations.select(&:one_to_one?).map(&:child)
end
has_ones?() click to toggle source
# File lib/generators/schofield/level.rb, line 116
def has_ones?
  @child_associations.any?(&:one_to_one?)
end
join?() click to toggle source

Join table

# File lib/generators/schofield/level.rb, line 59
def join?
  @join ||= @model.columns.select { |c| c.name.match(/_id$/) }.length == 2 && @model.columns.select { |c| !%w( id created_at updated_at position ).include?(c.name) }.length == 2
end
models?() click to toggle source
# File lib/generators/schofield/level.rb, line 147
def models?
  name != 'user'
end
multipart?() click to toggle source

Form

# File lib/generators/schofield/level.rb, line 166
def multipart?
  attachments? || has_ones.any?(&:attachments?)
end
nested?() click to toggle source

Nesting

# File lib/generators/schofield/level.rb, line 82
def nested?
  @parent_associations.any?(&:nest?)
end
nested_associations() click to toggle source
# File lib/generators/schofield/level.rb, line 90
def nested_associations
  if superclass? then []
  else
    associations = @child_associations + ( subclass? ? @superclass.child_associations : [] )
  end
end
nested_levels() click to toggle source
# File lib/generators/schofield/level.rb, line 97
def nested_levels
  nested_associations.select(&:nest?).map(&:child)
end
nests?() click to toggle source
# File lib/generators/schofield/level.rb, line 86
def nests?
  @child_associations.any?(&:nest?)
end
other_parent_name(parent_name) click to toggle source
# File lib/generators/schofield/level.rb, line 63
def other_parent_name parent_name
  @parent_associations.find{ |a| a.parent_name != parent_name }.parent_name
end
polymorphic?() click to toggle source

Polymorphism

# File lib/generators/schofield/level.rb, line 70
def polymorphic?
  @polymorphic ||= polymorphic_name.present?
end
polymorphic_attribute?(attribute) click to toggle source
# File lib/generators/schofield/level.rb, line 199
def polymorphic_attribute? attribute
  polymorphic_name && attribute.model_name == polymorphic_name
end
polymorphic_name() click to toggle source
# File lib/generators/schofield/level.rb, line 74
def polymorphic_name
  match_data = nil
  @polymorphic_name ||= @model.columns.find { |c| match_data = c.name.match(/^(.+)_type$/) } ? match_data[1] : nil
end
routes?() click to toggle source

Combos

# File lib/generators/schofield/level.rb, line 135
def routes?
  !nested? && !superclass? && !belongs_to_one? && !join?
end
sortable?() click to toggle source

Sortable

# File lib/generators/schofield/level.rb, line 159
def sortable?
  @sortable
end
subclass?() click to toggle source

Inheritence

# File lib/generators/schofield/level.rb, line 48
def subclass?
  @superclass.present?
end
superclass?() click to toggle source
# File lib/generators/schofield/level.rb, line 52
def superclass?
  @subclasses.any?
end
tables?() click to toggle source
# File lib/generators/schofield/level.rb, line 151
def tables?
  !belongs_to_one? && !superclass?
end
views?() click to toggle source
# File lib/generators/schofield/level.rb, line 143
def views?
  controllers? && !join?
end

Private Instance Methods

add_attribute(column) click to toggle source
# File lib/generators/schofield/level.rb, line 218
def add_attribute column
  attribute = @attributes.new_attribute(column, belongs_to_one_names.include?(column.name.gsub(/_id$/, '')))
  set_sortable if attribute.name == 'position'
end
add_attributes() click to toggle source
# File lib/generators/schofield/level.rb, line 211
def add_attributes
  @attributes = Attributes.new
  @model.columns.each do |column|
    add_attribute(column) unless ignore?(column) || (polymorphic? && column.name =~ /^#{polymorphic_name}_id$/)
  end
end
add_parent_associations() click to toggle source

Nesting refers to nested routes, embedding refers to nested_attributes_for Assuming that a polymorphic model has no parents other than it’s polymorphically associated parents If model has a one-to-one relationship with a parent, no nesting will occur as child will be embedded in parent Only allowing child to be nested under one parent or if polymorphic, the polymorphically associated parents

# File lib/generators/schofield/level.rb, line 234
def add_parent_associations

  if polymorphic?

    answer = Responses.get("Which models are #{polymorphic_name}?")
    answer.split(/[^\w]+/).map(&:underscore).each do |parent_name|
      @parent_associations << Association.new(self, parent_name, one_to_one?(polymorphic_name), polymorphic_name)
    end

  else

    any_one_to_ones = false
    @model.columns.each do |column|
      if (match_data = column.name.match(/^(.+)_id$/)).present? && Levels.exists?(match_data[1])
        parent_name = match_data[1]
        is_one_to_one = one_to_one?(parent_name)
        any_one_to_ones = true if is_one_to_one
        @parent_associations << Association.new(self, parent_name, is_one_to_one)
      end
    end

    if @parent_associations.any? && !any_one_to_ones
      @parent_associations.length == 1 ? ask_if_nested : ask_where_to_nest
    end
  end
end
ask_if_nested() click to toggle source
# File lib/generators/schofield/level.rb, line 265
def ask_if_nested
  question = "Do you wish to nest #{@human_name} in #{@parent_associations.first.parent_name}? [yes]"
  @parent_associations.first.nest = true unless %w( n no ).include?(Responses.get(question).downcase.strip)
end
ask_where_to_nest() click to toggle source
# File lib/generators/schofield/level.rb, line 270
def ask_where_to_nest
  question = "Where do you wish to nest #{@human_name}? nowhere(n), "
  question += @parent_associations.enum_with_index.map{ |n,i| "#{n.parent_name.gsub('_', ' ')}(#{i})" }.join(', ') + ' [n]'
  answer = Responses.get(question)
  @parent_associations[answer.to_i].nest = true unless answer == 'n' || answer.blank?
end
ignore?(column) click to toggle source
# File lib/generators/schofield/level.rb, line 277
def ignore? column
  self.class.columns_to_ignore.each do |string|
    return true if column.name.match(/#{string}/)
  end
  column.primary
end
one_to_one?(parent_name) click to toggle source
# File lib/generators/schofield/level.rb, line 261
def one_to_one? parent_name
  @one_to_one ||= %w( y yes ).include?(Responses.get("#{parent_name.gsub('_', ' ')} HAS ONE #{@human_name}? [N]").downcase)
end
set_sortable() click to toggle source
# File lib/generators/schofield/level.rb, line 223
def set_sortable
  unless superclass?
    @sortable = true
    Levels.sortable = @name
  end
end