module Pickle::Session

Public Class Methods

extended(world_object) click to toggle source
# File lib/pickle/session.rb, line 24
def extended(world_object)
  proxy_to_pickle_parser(class << world_object; self; end) # metaclass is not 2.1 compatible
end
included(world_class) click to toggle source
# File lib/pickle/session.rb, line 20
def included(world_class)
  proxy_to_pickle_parser(world_class)
end

Protected Class Methods

proxy_to_pickle_parser(world_class) click to toggle source
# File lib/pickle/session.rb, line 29
def proxy_to_pickle_parser(world_class)
  world_class.class_eval do
    unless methods.include?('method_missing_with_pickle_parser')
      alias_method_chain :method_missing, :pickle_parser
      alias_method_chain :respond_to?, :pickle_parser
    end
  end
end

Public Instance Methods

build_model(pickle_ref, fields = nil) click to toggle source
# File lib/pickle/session.rb, line 47
def build_model(pickle_ref, fields = nil)
  create_or_build_model(:build, 1, pickle_ref, fields)
end
build_models(count, pickle_ref, fields = nil) click to toggle source
# File lib/pickle/session.rb, line 51
def build_models(count, pickle_ref, fields = nil)
  create_or_build_model(:build, count, pickle_ref, fields)
end
create_model(pickle_ref, fields = nil) click to toggle source
# File lib/pickle/session.rb, line 39
def create_model(pickle_ref, fields = nil)
  create_or_build_model(:create, 1, pickle_ref, fields)
end
create_models(count, pickle_ref, fields = nil) click to toggle source
# File lib/pickle/session.rb, line 43
def create_models(count, pickle_ref, fields = nil)
  create_or_build_model(:create, count, pickle_ref, fields)
end
create_models_from_table(plural_factory, table) click to toggle source

if a column exists in the table which matches the singular factory name, this is used as the pickle ref

# File lib/pickle/session.rb, line 56
def create_models_from_table(plural_factory, table)
  factory = plural_factory.singularize
  table.hashes.map do |hash|
    pickle_ref = factory + (hash[factory] ? " \"#{hash.delete(factory)}\"" : "")
    create_model(pickle_ref, hash)
  end
end
created_model(name) click to toggle source

return the original model stored by #create_model or #find_model

# File lib/pickle/session.rb, line 105
def created_model(name)
  factory, name_or_index = *parse_model(name)

  if name_or_index.blank?
    models_by_index(factory).last
  elsif name_or_index.is_a?(Integer)
    models_by_index(factory)[name_or_index]
  else
    models_by_name(factory)[name_or_index] or raise ModelNotKnownError, name
  end
end
created_model!(name) click to toggle source

like #created_model, but raise an error if it can't be found

# File lib/pickle/session.rb, line 140
def created_model!(name)
  created_model(name) or raise ModelNotKnownError, name
end
created_model?(name) click to toggle source

predicate version which raises no errors

# File lib/pickle/session.rb, line 118
def created_model?(name)
  (created_model(name) rescue nil) ? true : false
end
created_models(factory) click to toggle source

return all original models of specified type

# File lib/pickle/session.rb, line 145
def created_models(factory)
  models_by_index(factory)
end
find_model(a_model_name, fields = nil) click to toggle source
# File lib/pickle/session.rb, line 64
def find_model(a_model_name, fields = nil)
  factory, name = *parse_model(a_model_name)

  raise ArgumentError, "Can't find a model with an ordinal (e.g. 1st user)" if name.is_a?(Integer)

  model_class = pickle_config.factories[factory].klass
  fields      = fields.is_a?(Hash) ? parse_hash(fields) : parse_fields(fields)
  conditions  = convert_models_to_attributes(model_class, fields)
  record      = Pickle::Adapter.find_first_model(model_class, conditions)

  store_model(factory, name, record) if record

  record
end
find_model!(name, fields = nil) click to toggle source
# File lib/pickle/session.rb, line 79
def find_model!(name, fields = nil)
  find_model(name, fields) or raise ModelNotFoundError, "Can't find #{name}#{" with #{fields}" if fields.present?} from the orm in this scenario"
end
find_models(factory, fields = nil) click to toggle source
# File lib/pickle/session.rb, line 83
def find_models(factory, fields = nil)
  factory = pickle_parser.canonical(factory)

  models_by_index(factory).clear

  model_class = pickle_config.factories[factory].klass
  conditions  = convert_models_to_attributes(model_class, parse_fields(fields))
  records     = Pickle::Adapter.find_all_models(model_class, conditions)

  records.each {|record| store_model(factory, nil, record)}
end
find_models_from_table(plural_factory, table) click to toggle source

if a column exists in the table which matches the singular factory name, this is used as the pickle ref

# File lib/pickle/session.rb, line 96
def find_models_from_table(plural_factory, table)
  factory = plural_factory.singularize
  table.hashes.map do |hash|
    pickle_ref = factory + (hash[factory] ? " \"#{hash.delete(factory)}\"" : "")
    find_model(pickle_ref, hash)
  end
end
model(name) click to toggle source

return a newly selected model

# File lib/pickle/session.rb, line 123
def model(name)
  model = created_model(name)
  return nil unless model
  Pickle::Adapter.get_model(model.class, model.id)
end
model!(name) click to toggle source

like model, but raise an error if it can't be found

# File lib/pickle/session.rb, line 135
def model!(name)
  model(name) or raise ModelNotKnownError, name
end
model?(name) click to toggle source

predicate version which raises no errors

# File lib/pickle/session.rb, line 130
def model?(name)
  (model(name) rescue nil) ? true : false
end
models(factory) click to toggle source

return all models of specified type (freshly selected from the database)

# File lib/pickle/session.rb, line 150
def models(factory)
  created_models(factory).map do |model|
    Pickle::Adapter.get_model(model.class, model.id)
  end
end
respond_to_with_pickle_parser?(method, include_private = false) click to toggle source
# File lib/pickle/session.rb, line 156
def respond_to_with_pickle_parser?(method, include_private = false)
  respond_to_without_pickle_parser?(method, include_private) || pickle_parser.respond_to?(method, include_private)
end

Protected Instance Methods

convert_models_to_attributes(klass, attrs) click to toggle source
# File lib/pickle/session.rb, line 195
def convert_models_to_attributes(klass, attrs)
  columns = nil
  conditions = {}

  attrs.each do |key, val|
    if supported = supported_association_model_type?(val) or val.nil?
      columns ||= Pickle::Adapter.column_names(klass)
    end

    if supported && columns.include?("#{key}_id")
      conditions["#{key}_id"] = val.id
      conditions["#{key}_type"] = val.class.base_class.name if columns.include?("#{key}_type")
    elsif val.nil? && columns.include?("#{key}_id") && !columns.include?("#{key}")
      # NOOP
    else
      conditions[key] = val
    end
  end

  conditions
end
create_or_build_model(method, count, pickle_ref, fields = nil) click to toggle source
# File lib/pickle/session.rb, line 161
def create_or_build_model(method, count, pickle_ref, fields = nil)
  factory, label = *parse_model(pickle_ref)
  raise ArgumentError, "Can't #{method} with an ordinal (e.g. 1st user)" if label.is_a?(Integer)
  fields = fields.is_a?(Hash) ? parse_hash(fields) : parse_fields(fields)

  count.to_i.times.map do
    record = pickle_config.factories[factory].send(method, fields)
    store_model(factory, label, record)
    return record if count == 1
    record
  end
end
method_missing_with_pickle_parser(method, *args, &block) click to toggle source
# File lib/pickle/session.rb, line 174
def method_missing_with_pickle_parser(method, *args, &block)
  if pickle_parser.respond_to?(method)
    pickle_parser.send(method, *args, &block)
  else
    method_missing_without_pickle_parser(method, *args, &block)
  end
end
models_by_index(factory) click to toggle source
# File lib/pickle/session.rb, line 228
def models_by_index(factory)
  @models_by_index ||= {}
  @models_by_index[pickle_parser.canonical(factory)] ||= []
end
models_by_name(factory) click to toggle source
# File lib/pickle/session.rb, line 223
def models_by_name(factory)
  @models_by_name ||= {}
  @models_by_name[pickle_parser.canonical(factory)] ||= {}
end
pickle_config() click to toggle source
# File lib/pickle/session.rb, line 191
def pickle_config
  pickle_parser.config
end
pickle_parser() click to toggle source
# File lib/pickle/session.rb, line 187
def pickle_parser
  @pickle_parser or self.pickle_parser = Pickle.parser
end
pickle_parser=(parser) click to toggle source
# File lib/pickle/session.rb, line 182
def pickle_parser=(parser)
  parser.session = self
  @pickle_parser = parser
end
store_model(factory, name, record) click to toggle source

if the factory name != the model name, store under both names

# File lib/pickle/session.rb, line 234
def store_model(factory, name, record)
  store_record(record.class.name, name, record) unless pickle_parser.canonical(factory) == pickle_parser.canonical(record.class.name)
  store_record(factory, name, record)
end
store_record(factory, name, record) click to toggle source
# File lib/pickle/session.rb, line 239
def store_record(factory, name, record)
  models_by_name(factory)[name] = record
  models_by_index(factory) << record
end
supported_association_model_type?(associated_model) click to toggle source
# File lib/pickle/session.rb, line 217
def supported_association_model_type?(associated_model)
  (defined?(ActiveRecord::Base) && associated_model.is_a?(ActiveRecord::Base)) ||
    (defined?(DataMapper::Model) && associated_model.is_a?(DataMapper::Model)) ||
    (defined?(Mongoid::Document) && associated_model.is_a?(Mongoid::Document))
end