EDIT: Para conseguir exactamente lo que busca más arriba, tendrá que utilizar esto para anular la incubadora por defecto en el archivo de modelo:
def path=(value)
self[:path] = connection.execute("SELECT text2ltree('#{value}');")[0][0]
end
A continuación, el código que tiene por encima de las obras.
Estoy interesado en aprender más sobre el funcionamiento interno de ActiveRecord y sus fundamentos de metaprogramación impenetrables, así que como ejercicio intenté lograr lo que describió en sus comentarios a continuación. He aquí un ejemplo que trabajó para mí (esto es todo en post.rb): salida
module DatabaseTransformation
extend ActiveSupport::Concern
module ClassMethods
def transformed_by_database(transformed_attributes = {})
transformed_attributes.each do |attr_name, transformation|
define_method("#{attr_name}=") do |argument|
transformed_value = connection.execute("SELECT #{transformation}('#{argument}');")[0][0]
write_attribute(attr_name, transformed_value)
end
end
end
end
end
class Post < ActiveRecord::Base
attr_accessible :name, :path, :version
include DatabaseTransformation
transformed_by_database :name => "length"
end
Consola:
1.9.3p194 :001 > p = Post.new(:name => "foo")
(0.3ms) SELECT length('foo');
=> #<Post id: nil, name: 3, path: nil, version: nil, created_at: nil, updated_at: nil>
En la vida real supongo que querría include
el módulo en ActiveRecord: : Base, en un archivo en algún lugar anterior de la ruta de carga. También tendría que manejar adecuadamente el tipo de argumento que está pasando a la función de base de datos. Finalmente, descubrí que cada adaptador de base de datos implementa connection.execute
, por lo que la forma de acceder al resultado puede ser diferente en Postgres (este ejemplo es SQLite3, donde el conjunto de resultados se devuelve como una matriz de hashes y la clave del primer registro de datos . es 0]
Este blog fue increíblemente útil:
http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-support-concern/
al igual que los carriles de guía para plug-in-autoría:
http://guides.rubyonrails.org/plugins.html
Además, por lo que vale, creo que en Postgres aún haría esto usando una migración para crear una regla de reescritura de consultas, pero esto resultó en una gran experiencia de aprendizaje. Espero que funcione y pueda dejar de pensar en cómo hacerlo ahora.
Puede escribir una función Postgres (procedimiento almacenado) y luego simplemente llamar a 'SELECT myfunc ('1.2.3')'. Puedo proporcionar un ejemplo si estás interesado en esa ruta. –