EDIT: To achieve exactly what you are looking for above, you should use this to override the default installer in your model file:
def path=(value) self[:path] = connection.execute("SELECT text2ltree('#{value}');")[0][0] end
Then the code that you have above works.
I'm interested in learning more about the internal components of ActiveRecord and its impenetrable basics of metaprogramming, as I tried to complete the exercise that you described in your comments below. Here is an example that worked for me (that's all in post.rb):
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
Console output:
1.9.3p194 :001 > p = Post.new(:name => "foo") (0.3ms) SELECT length('foo'); =>
In real life, I assume that you want to include module in ActiveRecord :: Base in a file somewhere earlier in the download path. You also need to properly handle the type of argument that you pass to the database functions. Finally, I found out that connection.execute is implemented by each database adapter, so the way to access the result may be different in Postgres (this example is SQLite3, where the result set is returned as an array of hashes and the key to the first data record is 0].
This blog post was incredibly helpful:
http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-support-concern/
as well as the Rails tutorial for creating plugins:
http://guides.rubyonrails.org/plugins.html
Also, for what it's worth, I think in Postgres I still do this through migration to create a request rewrite rule, but it did for great learning. Hope it works, and I can stop thinking about how to do it now.
Steve rowley
source share