module Hobo::Model

Constants

IncludeInSave
NAME_FIELD_GUESS
PRIMARY_CONTENT_GUESS
SEARCH_COLUMNS_GUESS

Public Instance Methods

get_creator() click to toggle source
# File lib/hobo/model.rb, line 401
def get_creator
  self.class.creator_attribute && send(self.class.creator_attribute)
end
set_creator(user) click to toggle source

We deliberately give these three methods unconventional (java-esque) names to avoid polluting the application namespace

# File lib/hobo/model.rb, line 376
def set_creator(user)
  set_creator!(user) unless get_creator
end
set_creator!(user) click to toggle source
# File lib/hobo/model.rb, line 381
def set_creator!(user)
  attr = self.class.creator_attribute
  return unless attr

  attr_type = self.class.creator_type

  # Is creator an instance, a string field or an association?
  if !attr_type.is_a?(Class)
    # attr_type is an instance - typically AssociationReflection for a polymorphic association
    self.send("#{attr}=", user)
  elsif self.class.attr_type(attr)._? <= String
    # Set it to the name of the current user
    self.send("#{attr}=", user.to_s) unless user.guest?
  else
    # Assume user is a user object, but don't set if we've got a type mismatch
    self.send("#{attr}=", user) if attr_type.nil? || user.is_a?(attr_type)
  end
end
to_param() click to toggle source
# File lib/hobo/model.rb, line 362
def to_param
  name_attr = self.class.name_attribute and name = send(name_attr)
  if name_attr && !name.blank? && id.is_a?(Fixnum)
    readable = name.to_s.downcase.gsub(/[^a-z0-9]+/, '-').remove(/-+$/).remove(/^-+/).split('-')[0..5].join('-')
    @to_param ||= "#{id}-#{readable}"
  else
    id.to_s
  end
end
to_s() click to toggle source
# File lib/hobo/model.rb, line 411
def to_s
  if self.class.name_attribute
    send self.class.name_attribute
  else
    "#{self.class.model_name.human} #{id}"
  end
end
to_url_path() click to toggle source
# File lib/hobo/model.rb, line 357
def to_url_path
  "#{self.class.to_url_path}/#{to_param}"
end
typed_id() click to toggle source
# File lib/hobo/model.rb, line 406
def typed_id
  "#{self.class.name.underscore}:#{self.id}" if id
end

Public Class Methods

all_models() click to toggle source
# File lib/hobo/model.rb, line 50
def self.all_models
  # Load every model in app/models...
  unless @models_loaded
    Dir.entries("#{Rails.root}/app/models/").each do |f|
      f =~ /^[a-zA-Z_][a-zA-Z0-9_]*\.rb$/ and f.sub(/.rb$/, '').camelize.constantize
    end
    @models_loaded = true
  end

  @model_names ||= Set.new
  # ...but only return the ones that registered themselves
  @model_names.map do |name|
    name.safe_constantize || (@model_names.delete name; nil)
  end.compact
end
belongs_to_with_accessible(name,*args, &block) click to toggle source

— belongs_to assignment support — #

# File lib/hobo/model/accessible_associations.rb, line 140
def self.belongs_to_with_accessible(name,*args, &block)
  if args.size == 0 || (args.size == 1 && args[0].kind_of?(Proc))
      options = {}
      args.push(options)
  elsif args.size == 1
      options = args[0]
  else
      options = args[1]
  end
  belongs_to_without_accessible(name,*args, &block)

  if options[:accessible]
    class_eval %Q{
      def #{name}_with_accessible=(record_hash_or_string)
        finder = Hobo::Model::AccessibleAssociations.finder_for_belongs_to(self, :#{name})
        record = Hobo::Model::AccessibleAssociations.find_or_create_and_update(self, :#{name}, finder, record_hash_or_string) do |id|
          if id
            raise ArgumentError, "attempted to update the wrong record in belongs_to association #{self}##{name}" unless
              #{name} && id.to_s == self.#{name}.id.to_s
            #{name}
          else
            finder.new
          end
        end
        self.#{name}_without_accessible = record
      end
    }, __FILE__, __LINE__ - 15
    alias_method_chain :"#{name}=", :accessible
  else
    # Not accessible - but finding by name and ID is still supported
    class_eval %Q{
      def #{name}_with_finder=(record_or_string)
        record = if record_or_string.is_a?(String)
                   finder = Hobo::Model::AccessibleAssociations.finder_for_belongs_to(self, :#{name})
                   Hobo::Model::AccessibleAssociations.find_by_name_or_id(finder, record_or_string)
                 else # it is a record
                   record_or_string
                 end
        self.#{name}_without_finder = record
      end
    }, __FILE__, __LINE__ - 12
    alias_method_chain :"#{name}=", :finder
  end
end
find_by_typed_id(typed_id) click to toggle source
# File lib/hobo/model.rb, line 67
def self.find_by_typed_id(typed_id)
  return nil if typed_id == 'nil'

  _, name, id, attr = *typed_id.match(/^([^:]+)(?::([^:]+)(?::([^:]+))?)?$/)
  raise ArgumentError.new("invalid typed-id: #{typed_id}") unless name

  model_class = name.camelize.safe_constantize or raise ArgumentError.new("no such class in typed-id: #{typed_id}")
  return nil unless model_class

  if id
    obj = model_class.find(id)
      # Optimise: can we use eager loading in the situation where the attr is a belongs_to?
      # We used to, but hit a bug in AR
    attr ? obj.send(attr) : obj
  else
    model_class
  end
end
has_many_with_accessible(name, *args, &block) click to toggle source

— has_many mass assignment support — #

# File lib/hobo/model/accessible_associations.rb, line 106
def self.has_many_with_accessible(name, *args, &block)
  # Rails 4 supports a lambda as the second argument in a has_many association
  # We need to support it too (required for gems like papertrail)
  # The problem is that when it is not used, the options hash is taken as the scope
  # To fix this, we make a small hack checking the second argument's class
  if args.size == 0 || (args.size == 1 && args[0].kind_of?(Proc))
      options = {}
      args.push(options)
  elsif args.size == 1
      options = args[0]
  else
      options = args[1]
  end
  has_many_without_accessible(name, *args, &block)
  # End of the received_scope hack

  if options[:accessible]
    class_eval %Q{
      def #{name}_with_accessible=(array_or_hash)
        __items = Hobo::Model::AccessibleAssociations.prepare_has_many_assignment(#{name}, :#{name}, array_or_hash)
        self.#{name}_without_accessible = __items
        # ensure the loaded array contains any changed records
        self.association(:#{name}).target[0..-1] = __items
      end
    }, __FILE__, __LINE__ - 7
    alias_method_chain :"#{name}=", :accessible
  end
end
included(base) click to toggle source
# File lib/hobo/model.rb, line 13
def self.included(base)
  base.extend(ClassMethods)

  register_model(base)

  base.class_eval do
    inheriting_cattr_reader :default_order

    cattr_accessor :hobo_controller
    self.hobo_controller = {}

    include Permissions
    include Lifecycles::ModelExtensions
    include FindFor
    include AccessibleAssociations
    include IncludeInSave
  end

  class << base
    alias_method_chain :belongs_to,    :creator_metadata
    alias_method_chain :belongs_to,    :test_methods
    alias_method_chain :attr_accessor, :creator_metadata

    alias_method_chain :has_one, :new_method
  end

  base.fields(false) # force hobo_fields to load

  included_in_class_callbacks(base)
end
register_model(model) click to toggle source
# File lib/hobo/model.rb, line 44
def self.register_model(model)
  @model_names ||= Set.new
  @model_names << model.name
end