Created
November 20, 2009 09:36
-
-
Save silvioq/239382 to your computer and use it in GitHub Desktop.
Best Describe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# BestDescribeRecord | |
module ActiveRecord | |
# Best Describe! | |
class Base | |
# Definición de cómo describir al registro | |
# Si no se ha especificado el "best_describe", | |
# entones el plugin intentará descubrir cómo | |
# mejor descibir al registro ... Si hay un atributo | |
# :name, entones lo usa. Si no, toma el primer atributo | |
# del tipo string. | |
# | |
# Uso: | |
# class Client | |
# best_describe { |r| "#{r[:last_name]}, #{r[:first_name]}" } | |
# end | |
# Client.find(:first).best_describe | |
# | |
# class Product | |
# best_describe :desription | |
# end | |
# Product.find(:first).best_describe | |
# | |
def self.best_describe(what=nil,&proc) | |
if proc | |
@best_describe = proc | |
else | |
@best_describe = what.to_sym | |
end | |
end | |
# Descubre qué atributo describe mejor al | |
# registro | |
def self.best_describe_discover | |
if column_names.include? "name" | |
best_describe :name | |
else | |
content_columns.each{ |col| | |
if col.type.to_sym == :string | |
best_describe col.name.to_sym | |
return | |
end | |
} | |
if content_columns[0] | |
best_describe content_columns[0].name.to_sym | |
return | |
else | |
best_describe columns[0].name.to_sym | |
end | |
end | |
end | |
# Devuelve la definición de cómo describir | |
def self.best_describe_def; @best_describe; end | |
# Uso: | |
# Client.find(:first).best_describe | |
def best_describe | |
d = self.class.best_describe_def | |
if d.nil? | |
self.class.best_describe_discover | |
d = self.class.best_describe_def | |
end | |
raise "No puedo describir al registro" if d.nil? | |
if d.class == Symbol and d.respond_to? d | |
self.send d | |
elsif d.class == Symbol | |
self[d] | |
elsif d.class == Proc | |
d.call self | |
else | |
"No describe" | |
end | |
end | |
# | |
# | |
# = Best describe column | |
# Define como se describe una columna | |
# Parametros | |
# - Nombre de la columna | |
# - Forma de describir: :self, :proc, :reflection, :constant, :description_method o :describe_method | |
# - Parámetro auxiliar: Para :reflection es el nombre de la misma y para :constant el nombre de la constante | |
def self.best_describe_column( column, way, param = nil, &proc ) | |
raise "#{column} no es una columna" unless self.columns_hash[column.to_s] | |
raise "Parámetro #{way} incorrecto" unless [:self, :reflection, :proc, :constant, :description_method, :describe_method].include? way | |
raise "#{param} no es una constante" if way == :constant and !self.constants.include? param | |
raise "#{param} no es una refleccion" if way == :reflection and !self.reflections[param] | |
@best_describe_columns[column.to_sym] = { :way => way, :param => param, :proc => proc } | |
end | |
def self.column_belongs_to_discover(column) | |
self.reflections.each{ |name,r| | |
return r.name if r.macro == :belongs_to and r.primary_key_name.to_s == column.to_s | |
} | |
false | |
end | |
# Descubre la mejor forma de describir una columna ... | |
# Si es un belongs_to, devuelve descripción del registro | |
# asociado en la tabla externa. | |
# Si existe la función [columna]_description o [columna]_describe, | |
# devuelve eso. | |
# Si existe la constante columna.pluralize.upcase y es un hash, | |
# intenta con eso. | |
# Si no, devuelve el valor del dato. | |
# | |
def self.best_describe_column_discover(column) | |
# Chequeo por un belongs to ... | |
reflection_name = column_belongs_to_discover(column) | |
if reflection_name | |
return self.best_describe_column column, :reflection, reflection_name | |
end | |
# Existe "#{column}_description" | |
if self.instance_methods.include? "#{column}_description" | |
return self.best_describe_column column, :description_method | |
end | |
# Existe "#{column}_describe" | |
if self.instance_methods.include? "#{column}_describe" | |
return self.best_describe_column column, :describe_method | |
end | |
# Existe constante? | |
if self.constants.include? column.to_s.pluralize.upcase | |
return self.best_describe_column column, :constant, column.to_s.pluralize.upcase | |
end | |
self.best_describe_column column, :self | |
end | |
# Devuelve la definición de cómo describir | |
def self.best_describe_column_def(column); | |
@best_describe_columns = {} unless @best_describe_columns | |
desc = @best_describe_columns[column.to_sym] | |
return desc if desc | |
best_describe_column_discover(column.to_sym) | |
end | |
# Devuelve la forma de describir a la columna | |
def best_describe_column(column) | |
d = self.class.best_describe_column_def column | |
raise "No puedo describir a #{column}" if d.nil? | |
case d[:way] | |
when :self | |
self.send column | |
when :reflection | |
r = self.send(d[:param]) | |
r.best_describe if r | |
when :constant | |
eval "self.class::#{d[:param]}[\"#{self.send column}\"]" | |
when :description_method | |
self.send( column.to_s + "_description" ) | |
when :describe_method | |
self.send( column.to_s + "_describe" ) | |
when :proc | |
d[:proc].call self | |
end | |
end | |
# Devuelve los elementos para una selección de la columna. | |
def best_describe_column_selection(column) | |
d = self.class.best_describe_column_def column | |
raise "No puedo describir a #{column}" if d.nil? | |
case d[:way] | |
when :self, :proc | |
[] | |
when :reflection | |
eval(d[:param].camelize).find(:all).collect{ |rec| | |
[rec.best_describe, rec.id] | |
} | |
when :constant | |
eval( "self.class::#{d[:param]}" ).collect{ |k,v| [v,k] } | |
when :description_method, :describe_method | |
if self.constants.include? column.to_s.pluralize.upcase | |
eval( "self.class::#{d[:param]}" ).collect{ |k,v| [v,k] } | |
else | |
[] | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment